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"
21 #include "llvm/Support/Compiler.h"
27 /// ObjCStringLiteral, used for Objective-C string literals
29 class ObjCStringLiteral : public Expr {
33 ObjCStringLiteral(StringLiteral *SL, QualType T, SourceLocation L)
34 : Expr(ObjCStringLiteralClass, T, VK_RValue, OK_Ordinary, false, false,
36 String(SL), AtLoc(L) {}
37 explicit ObjCStringLiteral(EmptyShell Empty)
38 : Expr(ObjCStringLiteralClass, Empty) {}
40 StringLiteral *getString() { return cast<StringLiteral>(String); }
41 const StringLiteral *getString() const { return cast<StringLiteral>(String); }
42 void setString(StringLiteral *S) { String = S; }
44 SourceLocation getAtLoc() const { return AtLoc; }
45 void setAtLoc(SourceLocation L) { AtLoc = L; }
47 SourceRange getSourceRange() const LLVM_READONLY {
48 return SourceRange(AtLoc, String->getLocEnd());
51 static bool classof(const Stmt *T) {
52 return T->getStmtClass() == ObjCStringLiteralClass;
54 static bool classof(const ObjCStringLiteral *) { return true; }
57 child_range children() { return child_range(&String, &String+1); }
60 /// ObjCBoolLiteralExpr - Objective-C Boolean Literal.
62 class ObjCBoolLiteralExpr : public Expr {
66 ObjCBoolLiteralExpr(bool val, QualType Ty, SourceLocation l) :
67 Expr(ObjCBoolLiteralExprClass, Ty, VK_RValue, OK_Ordinary, false, false,
68 false, false), Value(val), Loc(l) {}
70 explicit ObjCBoolLiteralExpr(EmptyShell Empty)
71 : Expr(ObjCBoolLiteralExprClass, Empty) { }
73 bool getValue() const { return Value; }
74 void setValue(bool V) { Value = V; }
76 SourceRange getSourceRange() const LLVM_READONLY { return SourceRange(Loc); }
78 SourceLocation getLocation() const { return Loc; }
79 void setLocation(SourceLocation L) { Loc = L; }
81 static bool classof(const Stmt *T) {
82 return T->getStmtClass() == ObjCBoolLiteralExprClass;
84 static bool classof(const ObjCBoolLiteralExpr *) { return true; }
87 child_range children() { return child_range(); }
90 /// ObjCBoxedExpr - used for generalized expression boxing.
91 /// as in: @(strdup("hello world")) or @(random())
92 /// Also used for boxing non-parenthesized numeric literals;
93 /// as in: @42 or \@true (c++/objc++) or \@__yes (c/objc).
94 class ObjCBoxedExpr : public Expr {
96 ObjCMethodDecl *BoxingMethod;
99 ObjCBoxedExpr(Expr *E, QualType T, ObjCMethodDecl *method,
101 : Expr(ObjCBoxedExprClass, T, VK_RValue, OK_Ordinary,
102 E->isTypeDependent(), E->isValueDependent(),
103 E->isInstantiationDependent(), E->containsUnexpandedParameterPack()),
104 SubExpr(E), BoxingMethod(method), Range(R) {}
105 explicit ObjCBoxedExpr(EmptyShell Empty)
106 : Expr(ObjCBoxedExprClass, Empty) {}
108 Expr *getSubExpr() { return cast<Expr>(SubExpr); }
109 const Expr *getSubExpr() const { return cast<Expr>(SubExpr); }
111 ObjCMethodDecl *getBoxingMethod() const {
115 SourceLocation getAtLoc() const { return Range.getBegin(); }
117 SourceRange getSourceRange() const LLVM_READONLY {
121 static bool classof(const Stmt *T) {
122 return T->getStmtClass() == ObjCBoxedExprClass;
124 static bool classof(const ObjCBoxedExpr *) { return true; }
127 child_range children() { return child_range(&SubExpr, &SubExpr+1); }
129 friend class ASTStmtReader;
132 /// ObjCArrayLiteral - used for objective-c array containers; as in:
133 /// @[@"Hello", NSApp, [NSNumber numberWithInt:42]];
134 class ObjCArrayLiteral : public Expr {
135 unsigned NumElements;
137 ObjCMethodDecl *ArrayWithObjectsMethod;
139 ObjCArrayLiteral(llvm::ArrayRef<Expr *> Elements,
140 QualType T, ObjCMethodDecl * Method,
143 explicit ObjCArrayLiteral(EmptyShell Empty, unsigned NumElements)
144 : Expr(ObjCArrayLiteralClass, Empty), NumElements(NumElements) {}
147 static ObjCArrayLiteral *Create(ASTContext &C,
148 llvm::ArrayRef<Expr *> Elements,
149 QualType T, ObjCMethodDecl * Method,
152 static ObjCArrayLiteral *CreateEmpty(ASTContext &C, unsigned NumElements);
154 SourceRange getSourceRange() const LLVM_READONLY { return Range; }
156 static bool classof(const Stmt *T) {
157 return T->getStmtClass() == ObjCArrayLiteralClass;
159 static bool classof(const ObjCArrayLiteral *) { return true; }
161 /// \brief Retrieve elements of array of literals.
162 Expr **getElements() { return reinterpret_cast<Expr **>(this + 1); }
164 /// \brief Retrieve elements of array of literals.
165 const Expr * const *getElements() const {
166 return reinterpret_cast<const Expr * const*>(this + 1);
169 /// getNumElements - Return number of elements of objective-c array literal.
170 unsigned getNumElements() const { return NumElements; }
172 /// getExpr - Return the Expr at the specified index.
173 Expr *getElement(unsigned Index) {
174 assert((Index < NumElements) && "Arg access out of range!");
175 return cast<Expr>(getElements()[Index]);
177 const Expr *getElement(unsigned Index) const {
178 assert((Index < NumElements) && "Arg access out of range!");
179 return cast<Expr>(getElements()[Index]);
182 ObjCMethodDecl *getArrayWithObjectsMethod() const {
183 return ArrayWithObjectsMethod;
187 child_range children() {
188 return child_range((Stmt **)getElements(),
189 (Stmt **)getElements() + NumElements);
192 friend class ASTStmtReader;
195 /// \brief An element in an Objective-C dictionary literal.
197 struct ObjCDictionaryElement {
198 /// \brief The key for the dictionary element.
201 /// \brief The value of the dictionary element.
204 /// \brief The location of the ellipsis, if this is a pack expansion.
205 SourceLocation EllipsisLoc;
207 /// \brief The number of elements this pack expansion will expand to, if
208 /// this is a pack expansion and is known.
209 llvm::Optional<unsigned> NumExpansions;
211 /// \brief Determines whether this dictionary element is a pack expansion.
212 bool isPackExpansion() const { return EllipsisLoc.isValid(); }
215 /// ObjCDictionaryLiteral - AST node to represent objective-c dictionary
216 /// literals; as in: @{@"name" : NSUserName(), @"date" : [NSDate date] };
217 class ObjCDictionaryLiteral : public Expr {
218 /// \brief Key/value pair used to store the key and value of a given element.
220 /// Objects of this type are stored directly after the expression.
221 struct KeyValuePair {
226 /// \brief Data that describes an element that is a pack expansion, used if any
227 /// of the elements in the dictionary literal are pack expansions.
228 struct ExpansionData {
229 /// \brief The location of the ellipsis, if this element is a pack
231 SourceLocation EllipsisLoc;
233 /// \brief If non-zero, the number of elements that this pack
234 /// expansion will expand to (+1).
235 unsigned NumExpansionsPlusOne;
238 /// \brief The number of elements in this dictionary literal.
239 unsigned NumElements : 31;
241 /// \brief Determine whether this dictionary literal has any pack expansions.
243 /// If the dictionary literal has pack expansions, then there will
244 /// be an array of pack expansion data following the array of
245 /// key/value pairs, which provide the locations of the ellipses (if
246 /// any) and number of elements in the expansion (if known). If
247 /// there are no pack expansions, we optimize away this storage.
248 unsigned HasPackExpansions : 1;
251 ObjCMethodDecl *DictWithObjectsMethod;
253 ObjCDictionaryLiteral(ArrayRef<ObjCDictionaryElement> VK,
254 bool HasPackExpansions,
255 QualType T, ObjCMethodDecl *method,
258 explicit ObjCDictionaryLiteral(EmptyShell Empty, unsigned NumElements,
259 bool HasPackExpansions)
260 : Expr(ObjCDictionaryLiteralClass, Empty), NumElements(NumElements),
261 HasPackExpansions(HasPackExpansions) {}
263 KeyValuePair *getKeyValues() {
264 return reinterpret_cast<KeyValuePair *>(this + 1);
267 const KeyValuePair *getKeyValues() const {
268 return reinterpret_cast<const KeyValuePair *>(this + 1);
271 ExpansionData *getExpansionData() {
272 if (!HasPackExpansions)
275 return reinterpret_cast<ExpansionData *>(getKeyValues() + NumElements);
278 const ExpansionData *getExpansionData() const {
279 if (!HasPackExpansions)
282 return reinterpret_cast<const ExpansionData *>(getKeyValues()+NumElements);
286 static ObjCDictionaryLiteral *Create(ASTContext &C,
287 ArrayRef<ObjCDictionaryElement> VK,
288 bool HasPackExpansions,
289 QualType T, ObjCMethodDecl *method,
292 static ObjCDictionaryLiteral *CreateEmpty(ASTContext &C,
293 unsigned NumElements,
294 bool HasPackExpansions);
296 /// getNumElements - Return number of elements of objective-c dictionary
298 unsigned getNumElements() const { return NumElements; }
300 ObjCDictionaryElement getKeyValueElement(unsigned Index) const {
301 assert((Index < NumElements) && "Arg access out of range!");
302 const KeyValuePair &KV = getKeyValues()[Index];
303 ObjCDictionaryElement Result = { KV.Key, KV.Value, SourceLocation(),
304 llvm::Optional<unsigned>() };
305 if (HasPackExpansions) {
306 const ExpansionData &Expansion = getExpansionData()[Index];
307 Result.EllipsisLoc = Expansion.EllipsisLoc;
308 if (Expansion.NumExpansionsPlusOne > 0)
309 Result.NumExpansions = Expansion.NumExpansionsPlusOne - 1;
314 ObjCMethodDecl *getDictWithObjectsMethod() const
315 { return DictWithObjectsMethod; }
317 SourceRange getSourceRange() const LLVM_READONLY { return Range; }
319 static bool classof(const Stmt *T) {
320 return T->getStmtClass() == ObjCDictionaryLiteralClass;
322 static bool classof(const ObjCDictionaryLiteral *) { return true; }
325 child_range children() {
326 // Note: we're taking advantage of the layout of the KeyValuePair struct
327 // here. If that struct changes, this code will need to change as well.
328 return child_range(reinterpret_cast<Stmt **>(this + 1),
329 reinterpret_cast<Stmt **>(this + 1) + NumElements * 2);
332 friend class ASTStmtReader;
333 friend class ASTStmtWriter;
337 /// ObjCEncodeExpr, used for \@encode in Objective-C. \@encode has the same
338 /// type and behavior as StringLiteral except that the string initializer is
339 /// obtained from ASTContext with the encoding type as an argument.
340 class ObjCEncodeExpr : public Expr {
341 TypeSourceInfo *EncodedType;
342 SourceLocation AtLoc, RParenLoc;
344 ObjCEncodeExpr(QualType T, TypeSourceInfo *EncodedType,
345 SourceLocation at, SourceLocation rp)
346 : Expr(ObjCEncodeExprClass, T, VK_LValue, OK_Ordinary,
347 EncodedType->getType()->isDependentType(),
348 EncodedType->getType()->isDependentType(),
349 EncodedType->getType()->isInstantiationDependentType(),
350 EncodedType->getType()->containsUnexpandedParameterPack()),
351 EncodedType(EncodedType), AtLoc(at), RParenLoc(rp) {}
353 explicit ObjCEncodeExpr(EmptyShell Empty) : Expr(ObjCEncodeExprClass, Empty){}
356 SourceLocation getAtLoc() const { return AtLoc; }
357 void setAtLoc(SourceLocation L) { AtLoc = L; }
358 SourceLocation getRParenLoc() const { return RParenLoc; }
359 void setRParenLoc(SourceLocation L) { RParenLoc = L; }
361 QualType getEncodedType() const { return EncodedType->getType(); }
363 TypeSourceInfo *getEncodedTypeSourceInfo() const { return EncodedType; }
364 void setEncodedTypeSourceInfo(TypeSourceInfo *EncType) {
365 EncodedType = EncType;
368 SourceRange getSourceRange() const LLVM_READONLY {
369 return SourceRange(AtLoc, RParenLoc);
372 static bool classof(const Stmt *T) {
373 return T->getStmtClass() == ObjCEncodeExprClass;
375 static bool classof(const ObjCEncodeExpr *) { return true; }
378 child_range children() { return child_range(); }
381 /// ObjCSelectorExpr used for \@selector in Objective-C.
382 class ObjCSelectorExpr : public Expr {
384 SourceLocation AtLoc, RParenLoc;
386 ObjCSelectorExpr(QualType T, Selector selInfo,
387 SourceLocation at, SourceLocation rp)
388 : Expr(ObjCSelectorExprClass, T, VK_RValue, OK_Ordinary, false, false,
390 SelName(selInfo), AtLoc(at), RParenLoc(rp){}
391 explicit ObjCSelectorExpr(EmptyShell Empty)
392 : Expr(ObjCSelectorExprClass, Empty) {}
394 Selector getSelector() const { return SelName; }
395 void setSelector(Selector S) { SelName = S; }
397 SourceLocation getAtLoc() const { return AtLoc; }
398 SourceLocation getRParenLoc() const { return RParenLoc; }
399 void setAtLoc(SourceLocation L) { AtLoc = L; }
400 void setRParenLoc(SourceLocation L) { RParenLoc = L; }
402 SourceRange getSourceRange() const LLVM_READONLY {
403 return SourceRange(AtLoc, RParenLoc);
406 /// getNumArgs - Return the number of actual arguments to this call.
407 unsigned getNumArgs() const { return SelName.getNumArgs(); }
409 static bool classof(const Stmt *T) {
410 return T->getStmtClass() == ObjCSelectorExprClass;
412 static bool classof(const ObjCSelectorExpr *) { return true; }
415 child_range children() { return child_range(); }
418 /// ObjCProtocolExpr used for protocol expression in Objective-C. This is used
419 /// as: @protocol(foo), as in:
420 /// obj conformsToProtocol:@protocol(foo)]
421 /// The return type is "Protocol*".
422 class ObjCProtocolExpr : public Expr {
423 ObjCProtocolDecl *TheProtocol;
424 SourceLocation AtLoc, ProtoLoc, RParenLoc;
426 ObjCProtocolExpr(QualType T, ObjCProtocolDecl *protocol,
427 SourceLocation at, SourceLocation protoLoc, SourceLocation rp)
428 : Expr(ObjCProtocolExprClass, T, VK_RValue, OK_Ordinary, false, false,
430 TheProtocol(protocol), AtLoc(at), ProtoLoc(protoLoc), RParenLoc(rp) {}
431 explicit ObjCProtocolExpr(EmptyShell Empty)
432 : Expr(ObjCProtocolExprClass, Empty) {}
434 ObjCProtocolDecl *getProtocol() const { return TheProtocol; }
435 void setProtocol(ObjCProtocolDecl *P) { TheProtocol = P; }
437 SourceLocation getProtocolIdLoc() const { return ProtoLoc; }
438 SourceLocation getAtLoc() const { return AtLoc; }
439 SourceLocation getRParenLoc() const { return RParenLoc; }
440 void setAtLoc(SourceLocation L) { AtLoc = L; }
441 void setRParenLoc(SourceLocation L) { RParenLoc = L; }
443 SourceRange getSourceRange() const LLVM_READONLY {
444 return SourceRange(AtLoc, RParenLoc);
447 static bool classof(const Stmt *T) {
448 return T->getStmtClass() == ObjCProtocolExprClass;
450 static bool classof(const ObjCProtocolExpr *) { return true; }
453 child_range children() { return child_range(); }
455 friend class ASTStmtReader;
456 friend class ASTStmtWriter;
459 /// ObjCIvarRefExpr - A reference to an ObjC instance variable.
460 class ObjCIvarRefExpr : public Expr {
464 bool IsArrow:1; // True if this is "X->F", false if this is "X.F".
465 bool IsFreeIvar:1; // True if ivar reference has no base (self assumed).
468 ObjCIvarRefExpr(ObjCIvarDecl *d, QualType t,
469 SourceLocation l, Expr *base,
470 bool arrow = false, bool freeIvar = false) :
471 Expr(ObjCIvarRefExprClass, t, VK_LValue, OK_Ordinary,
472 /*TypeDependent=*/false, base->isValueDependent(),
473 base->isInstantiationDependent(),
474 base->containsUnexpandedParameterPack()),
475 D(d), Base(base), Loc(l), IsArrow(arrow), IsFreeIvar(freeIvar) {}
477 explicit ObjCIvarRefExpr(EmptyShell Empty)
478 : Expr(ObjCIvarRefExprClass, Empty) {}
480 ObjCIvarDecl *getDecl() { return D; }
481 const ObjCIvarDecl *getDecl() const { return D; }
482 void setDecl(ObjCIvarDecl *d) { D = d; }
484 const Expr *getBase() const { return cast<Expr>(Base); }
485 Expr *getBase() { return cast<Expr>(Base); }
486 void setBase(Expr * base) { Base = base; }
488 bool isArrow() const { return IsArrow; }
489 bool isFreeIvar() const { return IsFreeIvar; }
490 void setIsArrow(bool A) { IsArrow = A; }
491 void setIsFreeIvar(bool A) { IsFreeIvar = A; }
493 SourceLocation getLocation() const { return Loc; }
494 void setLocation(SourceLocation L) { Loc = L; }
496 SourceRange getSourceRange() const LLVM_READONLY {
497 return isFreeIvar() ? SourceRange(Loc)
498 : SourceRange(getBase()->getLocStart(), Loc);
501 static bool classof(const Stmt *T) {
502 return T->getStmtClass() == ObjCIvarRefExprClass;
504 static bool classof(const ObjCIvarRefExpr *) { return true; }
507 child_range children() { return child_range(&Base, &Base+1); }
510 /// ObjCPropertyRefExpr - A dot-syntax expression to access an ObjC
512 class ObjCPropertyRefExpr : public Expr {
514 /// If the bool is true, this is an implicit property reference; the
515 /// pointer is an (optional) ObjCMethodDecl and Setter may be set.
516 /// if the bool is false, this is an explicit property reference;
517 /// the pointer is an ObjCPropertyDecl and Setter is always null.
518 llvm::PointerIntPair<NamedDecl*, 1, bool> PropertyOrGetter;
520 /// \brief Indicates whether the property reference will result in a message
521 /// to the getter, the setter, or both.
522 /// This applies to both implicit and explicit property references.
523 enum MethodRefFlags {
525 MethodRef_Getter = 0x1,
526 MethodRef_Setter = 0x2
529 /// \brief Contains the Setter method pointer and MethodRefFlags bit flags.
530 llvm::PointerIntPair<ObjCMethodDecl *, 2, unsigned> SetterAndMethodRefFlags;
532 // FIXME: Maybe we should store the property identifier here,
533 // because it's not rederivable from the other data when there's an
534 // implicit property with no getter (because the 'foo' -> 'setFoo:'
535 // transformation is lossy on the first character).
537 SourceLocation IdLoc;
539 /// \brief When the receiver in property access is 'super', this is
540 /// the location of the 'super' keyword. When it's an interface,
541 /// this is that interface.
542 SourceLocation ReceiverLoc;
543 llvm::PointerUnion3<Stmt*, const Type*, ObjCInterfaceDecl*> Receiver;
546 ObjCPropertyRefExpr(ObjCPropertyDecl *PD, QualType t,
547 ExprValueKind VK, ExprObjectKind OK,
548 SourceLocation l, Expr *base)
549 : Expr(ObjCPropertyRefExprClass, t, VK, OK,
550 /*TypeDependent=*/false, base->isValueDependent(),
551 base->isInstantiationDependent(),
552 base->containsUnexpandedParameterPack()),
553 PropertyOrGetter(PD, false), SetterAndMethodRefFlags(),
554 IdLoc(l), ReceiverLoc(), Receiver(base) {
555 assert(t->isSpecificPlaceholderType(BuiltinType::PseudoObject));
558 ObjCPropertyRefExpr(ObjCPropertyDecl *PD, QualType t,
559 ExprValueKind VK, ExprObjectKind OK,
560 SourceLocation l, SourceLocation sl, QualType st)
561 : Expr(ObjCPropertyRefExprClass, t, VK, OK,
562 /*TypeDependent=*/false, false, st->isInstantiationDependentType(),
563 st->containsUnexpandedParameterPack()),
564 PropertyOrGetter(PD, false), SetterAndMethodRefFlags(),
565 IdLoc(l), ReceiverLoc(sl), Receiver(st.getTypePtr()) {
566 assert(t->isSpecificPlaceholderType(BuiltinType::PseudoObject));
569 ObjCPropertyRefExpr(ObjCMethodDecl *Getter, ObjCMethodDecl *Setter,
570 QualType T, ExprValueKind VK, ExprObjectKind OK,
571 SourceLocation IdLoc, Expr *Base)
572 : Expr(ObjCPropertyRefExprClass, T, VK, OK, false,
573 Base->isValueDependent(), Base->isInstantiationDependent(),
574 Base->containsUnexpandedParameterPack()),
575 PropertyOrGetter(Getter, true), SetterAndMethodRefFlags(Setter, 0),
576 IdLoc(IdLoc), ReceiverLoc(), Receiver(Base) {
577 assert(T->isSpecificPlaceholderType(BuiltinType::PseudoObject));
580 ObjCPropertyRefExpr(ObjCMethodDecl *Getter, ObjCMethodDecl *Setter,
581 QualType T, ExprValueKind VK, ExprObjectKind OK,
582 SourceLocation IdLoc,
583 SourceLocation SuperLoc, QualType SuperTy)
584 : Expr(ObjCPropertyRefExprClass, T, VK, OK, false, false, false, false),
585 PropertyOrGetter(Getter, true), SetterAndMethodRefFlags(Setter, 0),
586 IdLoc(IdLoc), ReceiverLoc(SuperLoc), Receiver(SuperTy.getTypePtr()) {
587 assert(T->isSpecificPlaceholderType(BuiltinType::PseudoObject));
590 ObjCPropertyRefExpr(ObjCMethodDecl *Getter, ObjCMethodDecl *Setter,
591 QualType T, ExprValueKind VK, ExprObjectKind OK,
592 SourceLocation IdLoc,
593 SourceLocation ReceiverLoc, ObjCInterfaceDecl *Receiver)
594 : Expr(ObjCPropertyRefExprClass, T, VK, OK, false, false, false, false),
595 PropertyOrGetter(Getter, true), SetterAndMethodRefFlags(Setter, 0),
596 IdLoc(IdLoc), ReceiverLoc(ReceiverLoc), Receiver(Receiver) {
597 assert(T->isSpecificPlaceholderType(BuiltinType::PseudoObject));
600 explicit ObjCPropertyRefExpr(EmptyShell Empty)
601 : Expr(ObjCPropertyRefExprClass, Empty) {}
603 bool isImplicitProperty() const { return PropertyOrGetter.getInt(); }
604 bool isExplicitProperty() const { return !PropertyOrGetter.getInt(); }
606 ObjCPropertyDecl *getExplicitProperty() const {
607 assert(!isImplicitProperty());
608 return cast<ObjCPropertyDecl>(PropertyOrGetter.getPointer());
611 ObjCMethodDecl *getImplicitPropertyGetter() const {
612 assert(isImplicitProperty());
613 return cast_or_null<ObjCMethodDecl>(PropertyOrGetter.getPointer());
616 ObjCMethodDecl *getImplicitPropertySetter() const {
617 assert(isImplicitProperty());
618 return SetterAndMethodRefFlags.getPointer();
621 Selector getGetterSelector() const {
622 if (isImplicitProperty())
623 return getImplicitPropertyGetter()->getSelector();
624 return getExplicitProperty()->getGetterName();
627 Selector getSetterSelector() const {
628 if (isImplicitProperty())
629 return getImplicitPropertySetter()->getSelector();
630 return getExplicitProperty()->getSetterName();
633 /// \brief True if the property reference will result in a message to the
635 /// This applies to both implicit and explicit property references.
636 bool isMessagingGetter() const {
637 return SetterAndMethodRefFlags.getInt() & MethodRef_Getter;
640 /// \brief True if the property reference will result in a message to the
642 /// This applies to both implicit and explicit property references.
643 bool isMessagingSetter() const {
644 return SetterAndMethodRefFlags.getInt() & MethodRef_Setter;
647 void setIsMessagingGetter(bool val = true) {
648 setMethodRefFlag(MethodRef_Getter, val);
651 void setIsMessagingSetter(bool val = true) {
652 setMethodRefFlag(MethodRef_Setter, val);
655 const Expr *getBase() const {
656 return cast<Expr>(Receiver.get<Stmt*>());
659 return cast<Expr>(Receiver.get<Stmt*>());
662 SourceLocation getLocation() const { return IdLoc; }
664 SourceLocation getReceiverLocation() const { return ReceiverLoc; }
665 QualType getSuperReceiverType() const {
666 return QualType(Receiver.get<const Type*>(), 0);
668 QualType getGetterResultType() const {
670 if (isExplicitProperty()) {
671 const ObjCPropertyDecl *PDecl = getExplicitProperty();
672 if (const ObjCMethodDecl *Getter = PDecl->getGetterMethodDecl())
673 ResultType = Getter->getResultType();
675 ResultType = PDecl->getType();
677 const ObjCMethodDecl *Getter = getImplicitPropertyGetter();
679 ResultType = Getter->getResultType(); // with reference!
684 QualType getSetterArgType() const {
686 if (isImplicitProperty()) {
687 const ObjCMethodDecl *Setter = getImplicitPropertySetter();
688 ObjCMethodDecl::param_const_iterator P = Setter->param_begin();
689 ArgType = (*P)->getType();
691 if (ObjCPropertyDecl *PDecl = getExplicitProperty())
692 if (const ObjCMethodDecl *Setter = PDecl->getSetterMethodDecl()) {
693 ObjCMethodDecl::param_const_iterator P = Setter->param_begin();
694 ArgType = (*P)->getType();
696 if (ArgType.isNull())
702 ObjCInterfaceDecl *getClassReceiver() const {
703 return Receiver.get<ObjCInterfaceDecl*>();
705 bool isObjectReceiver() const { return Receiver.is<Stmt*>(); }
706 bool isSuperReceiver() const { return Receiver.is<const Type*>(); }
707 bool isClassReceiver() const { return Receiver.is<ObjCInterfaceDecl*>(); }
709 SourceRange getSourceRange() const LLVM_READONLY {
710 return SourceRange((isObjectReceiver() ? getBase()->getLocStart()
711 : getReceiverLocation()),
715 static bool classof(const Stmt *T) {
716 return T->getStmtClass() == ObjCPropertyRefExprClass;
718 static bool classof(const ObjCPropertyRefExpr *) { return true; }
721 child_range children() {
722 if (Receiver.is<Stmt*>()) {
723 Stmt **begin = reinterpret_cast<Stmt**>(&Receiver); // hack!
724 return child_range(begin, begin+1);
726 return child_range();
730 friend class ASTStmtReader;
731 friend class ASTStmtWriter;
732 void setExplicitProperty(ObjCPropertyDecl *D, unsigned methRefFlags) {
733 PropertyOrGetter.setPointer(D);
734 PropertyOrGetter.setInt(false);
735 SetterAndMethodRefFlags.setPointer(0);
736 SetterAndMethodRefFlags.setInt(methRefFlags);
738 void setImplicitProperty(ObjCMethodDecl *Getter, ObjCMethodDecl *Setter,
739 unsigned methRefFlags) {
740 PropertyOrGetter.setPointer(Getter);
741 PropertyOrGetter.setInt(true);
742 SetterAndMethodRefFlags.setPointer(Setter);
743 SetterAndMethodRefFlags.setInt(methRefFlags);
745 void setBase(Expr *Base) { Receiver = Base; }
746 void setSuperReceiver(QualType T) { Receiver = T.getTypePtr(); }
747 void setClassReceiver(ObjCInterfaceDecl *D) { Receiver = D; }
749 void setLocation(SourceLocation L) { IdLoc = L; }
750 void setReceiverLocation(SourceLocation Loc) { ReceiverLoc = Loc; }
752 void setMethodRefFlag(MethodRefFlags flag, bool val) {
753 unsigned f = SetterAndMethodRefFlags.getInt();
758 SetterAndMethodRefFlags.setInt(f);
762 /// ObjCSubscriptRefExpr - used for array and dictionary subscripting.
763 /// array[4] = array[3]; dictionary[key] = dictionary[alt_key];
765 class ObjCSubscriptRefExpr : public Expr {
766 // Location of ']' in an indexing expression.
767 SourceLocation RBracket;
768 // array/dictionary base expression.
769 // for arrays, this is a numeric expression. For dictionaries, this is
770 // an objective-c object pointer expression.
771 enum { BASE, KEY, END_EXPR };
772 Stmt* SubExprs[END_EXPR];
774 ObjCMethodDecl *GetAtIndexMethodDecl;
776 // For immutable objects this is null. When ObjCSubscriptRefExpr is to read
777 // an indexed object this is null too.
778 ObjCMethodDecl *SetAtIndexMethodDecl;
782 ObjCSubscriptRefExpr(Expr *base, Expr *key, QualType T,
783 ExprValueKind VK, ExprObjectKind OK,
784 ObjCMethodDecl *getMethod,
785 ObjCMethodDecl *setMethod, SourceLocation RB)
786 : Expr(ObjCSubscriptRefExprClass, T, VK, OK,
787 base->isTypeDependent() || key->isTypeDependent(),
788 base->isValueDependent() || key->isValueDependent(),
789 base->isInstantiationDependent() || key->isInstantiationDependent(),
790 (base->containsUnexpandedParameterPack() ||
791 key->containsUnexpandedParameterPack())),
793 GetAtIndexMethodDecl(getMethod),
794 SetAtIndexMethodDecl(setMethod)
795 {SubExprs[BASE] = base; SubExprs[KEY] = key;}
797 explicit ObjCSubscriptRefExpr(EmptyShell Empty)
798 : Expr(ObjCSubscriptRefExprClass, Empty) {}
800 static ObjCSubscriptRefExpr *Create(ASTContext &C,
802 Expr *key, QualType T,
803 ObjCMethodDecl *getMethod,
804 ObjCMethodDecl *setMethod,
807 SourceLocation getRBracket() const { return RBracket; }
808 void setRBracket(SourceLocation RB) { RBracket = RB; }
809 SourceRange getSourceRange() const LLVM_READONLY {
810 return SourceRange(SubExprs[BASE]->getLocStart(), RBracket);
813 static bool classof(const Stmt *T) {
814 return T->getStmtClass() == ObjCSubscriptRefExprClass;
816 static bool classof(const ObjCSubscriptRefExpr *) { return true; }
818 Expr *getBaseExpr() const { return cast<Expr>(SubExprs[BASE]); }
819 void setBaseExpr(Stmt *S) { SubExprs[BASE] = S; }
821 Expr *getKeyExpr() const { return cast<Expr>(SubExprs[KEY]); }
822 void setKeyExpr(Stmt *S) { SubExprs[KEY] = S; }
824 ObjCMethodDecl *getAtIndexMethodDecl() const {
825 return GetAtIndexMethodDecl;
828 ObjCMethodDecl *setAtIndexMethodDecl() const {
829 return SetAtIndexMethodDecl;
832 bool isArraySubscriptRefExpr() const {
833 return getKeyExpr()->getType()->isIntegralOrEnumerationType();
836 child_range children() {
837 return child_range(SubExprs, SubExprs+END_EXPR);
840 friend class ASTStmtReader;
844 /// \brief An expression that sends a message to the given Objective-C
847 /// The following contains two message send expressions:
850 /// [[NSString alloc] initWithString:@"Hello"]
853 /// The innermost message send invokes the "alloc" class method on the
854 /// NSString class, while the outermost message send invokes the
855 /// "initWithString" instance method on the object returned from
856 /// NSString's "alloc". In all, an Objective-C message send can take
857 /// on four different (although related) forms:
859 /// 1. Send to an object instance.
860 /// 2. Send to a class.
861 /// 3. Send to the superclass instance of the current class.
862 /// 4. Send to the superclass of the current class.
864 /// All four kinds of message sends are modeled by the ObjCMessageExpr
865 /// class, and can be distinguished via \c getReceiverKind(). Example:
867 class ObjCMessageExpr : public Expr {
868 /// \brief Stores either the selector that this message is sending
869 /// to (when \c HasMethod is zero) or an \c ObjCMethodDecl pointer
870 /// referring to the method that we type-checked against.
871 uintptr_t SelectorOrMethod;
873 enum { NumArgsBitWidth = 16 };
875 /// \brief The number of arguments in the message send, not
876 /// including the receiver.
877 unsigned NumArgs : NumArgsBitWidth;
879 void setNumArgs(unsigned Num) {
880 assert((Num >> NumArgsBitWidth) == 0 && "Num of args is out of range!");
884 /// \brief The kind of message send this is, which is one of the
885 /// ReceiverKind values.
887 /// We pad this out to a byte to avoid excessive masking and shifting.
890 /// \brief Whether we have an actual method prototype in \c
891 /// SelectorOrMethod.
893 /// When non-zero, we have a method declaration; otherwise, we just
895 unsigned HasMethod : 1;
897 /// \brief Whether this message send is a "delegate init call",
898 /// i.e. a call of an init method on self from within an init method.
899 unsigned IsDelegateInitCall : 1;
901 /// \brief Whether this message send was implicitly generated by
902 /// the implementation rather than explicitly written by the user.
903 unsigned IsImplicit : 1;
905 /// \brief Whether the locations of the selector identifiers are in a
906 /// "standard" position, a enum SelectorLocationsKind.
907 unsigned SelLocsKind : 2;
909 /// \brief When the message expression is a send to 'super', this is
910 /// the location of the 'super' keyword.
911 SourceLocation SuperLoc;
913 /// \brief The source locations of the open and close square
914 /// brackets ('[' and ']', respectively).
915 SourceLocation LBracLoc, RBracLoc;
917 ObjCMessageExpr(EmptyShell Empty, unsigned NumArgs)
918 : Expr(ObjCMessageExprClass, Empty), SelectorOrMethod(0), Kind(0),
919 HasMethod(0), IsDelegateInitCall(0), IsImplicit(0), SelLocsKind(0) {
923 ObjCMessageExpr(QualType T, ExprValueKind VK,
924 SourceLocation LBracLoc,
925 SourceLocation SuperLoc,
926 bool IsInstanceSuper,
929 ArrayRef<SourceLocation> SelLocs,
930 SelectorLocationsKind SelLocsK,
931 ObjCMethodDecl *Method,
932 ArrayRef<Expr *> Args,
933 SourceLocation RBracLoc,
935 ObjCMessageExpr(QualType T, ExprValueKind VK,
936 SourceLocation LBracLoc,
937 TypeSourceInfo *Receiver,
939 ArrayRef<SourceLocation> SelLocs,
940 SelectorLocationsKind SelLocsK,
941 ObjCMethodDecl *Method,
942 ArrayRef<Expr *> Args,
943 SourceLocation RBracLoc,
945 ObjCMessageExpr(QualType T, ExprValueKind VK,
946 SourceLocation LBracLoc,
949 ArrayRef<SourceLocation> SelLocs,
950 SelectorLocationsKind SelLocsK,
951 ObjCMethodDecl *Method,
952 ArrayRef<Expr *> Args,
953 SourceLocation RBracLoc,
956 void initArgsAndSelLocs(ArrayRef<Expr *> Args,
957 ArrayRef<SourceLocation> SelLocs,
958 SelectorLocationsKind SelLocsK);
960 /// \brief Retrieve the pointer value of the message receiver.
961 void *getReceiverPointer() const {
962 return *const_cast<void **>(
963 reinterpret_cast<const void * const*>(this + 1));
966 /// \brief Set the pointer value of the message receiver.
967 void setReceiverPointer(void *Value) {
968 *reinterpret_cast<void **>(this + 1) = Value;
971 SelectorLocationsKind getSelLocsKind() const {
972 return (SelectorLocationsKind)SelLocsKind;
974 bool hasStandardSelLocs() const {
975 return getSelLocsKind() != SelLoc_NonStandard;
978 /// \brief Get a pointer to the stored selector identifiers locations array.
979 /// No locations will be stored if HasStandardSelLocs is true.
980 SourceLocation *getStoredSelLocs() {
981 return reinterpret_cast<SourceLocation*>(getArgs() + getNumArgs());
983 const SourceLocation *getStoredSelLocs() const {
984 return reinterpret_cast<const SourceLocation*>(getArgs() + getNumArgs());
987 /// \brief Get the number of stored selector identifiers locations.
988 /// No locations will be stored if HasStandardSelLocs is true.
989 unsigned getNumStoredSelLocs() const {
990 if (hasStandardSelLocs())
992 return getNumSelectorLocs();
995 static ObjCMessageExpr *alloc(ASTContext &C,
996 ArrayRef<Expr *> Args,
997 SourceLocation RBraceLoc,
998 ArrayRef<SourceLocation> SelLocs,
1000 SelectorLocationsKind &SelLocsK);
1001 static ObjCMessageExpr *alloc(ASTContext &C,
1003 unsigned NumStoredSelLocs);
1006 /// \brief The kind of receiver this message is sending to.
1008 /// \brief The receiver is a class.
1010 /// \brief The receiver is an object instance.
1012 /// \brief The receiver is a superclass.
1014 /// \brief The receiver is the instance of the superclass object.
1018 /// \brief Create a message send to super.
1020 /// \param Context The ASTContext in which this expression will be created.
1022 /// \param T The result type of this message.
1024 /// \param VK The value kind of this message. A message returning
1025 /// a l-value or r-value reference will be an l-value or x-value,
1028 /// \param LBracLoc The location of the open square bracket '['.
1030 /// \param SuperLoc The location of the "super" keyword.
1032 /// \param IsInstanceSuper Whether this is an instance "super"
1033 /// message (otherwise, it's a class "super" message).
1035 /// \param Sel The selector used to determine which method gets called.
1037 /// \param Method The Objective-C method against which this message
1038 /// send was type-checked. May be NULL.
1040 /// \param Args The message send arguments.
1042 /// \param RBracLoc The location of the closing square bracket ']'.
1043 static ObjCMessageExpr *Create(ASTContext &Context, QualType T,
1045 SourceLocation LBracLoc,
1046 SourceLocation SuperLoc,
1047 bool IsInstanceSuper,
1050 ArrayRef<SourceLocation> SelLocs,
1051 ObjCMethodDecl *Method,
1052 ArrayRef<Expr *> Args,
1053 SourceLocation RBracLoc,
1056 /// \brief Create a class message send.
1058 /// \param Context The ASTContext in which this expression will be created.
1060 /// \param T The result type of this message.
1062 /// \param VK The value kind of this message. A message returning
1063 /// a l-value or r-value reference will be an l-value or x-value,
1066 /// \param LBracLoc The location of the open square bracket '['.
1068 /// \param Receiver The type of the receiver, including
1069 /// source-location information.
1071 /// \param Sel The selector used to determine which method gets called.
1073 /// \param Method The Objective-C method against which this message
1074 /// send was type-checked. May be NULL.
1076 /// \param Args The message send arguments.
1078 /// \param RBracLoc The location of the closing square bracket ']'.
1079 static ObjCMessageExpr *Create(ASTContext &Context, QualType T,
1081 SourceLocation LBracLoc,
1082 TypeSourceInfo *Receiver,
1084 ArrayRef<SourceLocation> SelLocs,
1085 ObjCMethodDecl *Method,
1086 ArrayRef<Expr *> Args,
1087 SourceLocation RBracLoc,
1090 /// \brief Create an instance message send.
1092 /// \param Context The ASTContext in which this expression will be created.
1094 /// \param T The result type of this message.
1096 /// \param VK The value kind of this message. A message returning
1097 /// a l-value or r-value reference will be an l-value or x-value,
1100 /// \param LBracLoc The location of the open square bracket '['.
1102 /// \param Receiver The expression used to produce the object that
1103 /// will receive this message.
1105 /// \param Sel The selector used to determine which method gets called.
1107 /// \param Method The Objective-C method against which this message
1108 /// send was type-checked. May be NULL.
1110 /// \param Args The message send arguments.
1112 /// \param RBracLoc The location of the closing square bracket ']'.
1113 static ObjCMessageExpr *Create(ASTContext &Context, QualType T,
1115 SourceLocation LBracLoc,
1118 ArrayRef<SourceLocation> SeLocs,
1119 ObjCMethodDecl *Method,
1120 ArrayRef<Expr *> Args,
1121 SourceLocation RBracLoc,
1124 /// \brief Create an empty Objective-C message expression, to be
1125 /// filled in by subsequent calls.
1127 /// \param Context The context in which the message send will be created.
1129 /// \param NumArgs The number of message arguments, not including
1131 static ObjCMessageExpr *CreateEmpty(ASTContext &Context,
1133 unsigned NumStoredSelLocs);
1135 /// \brief Indicates whether the message send was implicitly
1136 /// generated by the implementation. If false, it was written explicitly
1137 /// in the source code.
1138 bool isImplicit() const { return IsImplicit; }
1140 /// \brief Determine the kind of receiver that this message is being
1142 ReceiverKind getReceiverKind() const { return (ReceiverKind)Kind; }
1144 /// \brief Source range of the receiver.
1145 SourceRange getReceiverRange() const;
1147 /// \brief Determine whether this is an instance message to either a
1148 /// computed object or to super.
1149 bool isInstanceMessage() const {
1150 return getReceiverKind() == Instance || getReceiverKind() == SuperInstance;
1153 /// \brief Determine whether this is an class message to either a
1154 /// specified class or to super.
1155 bool isClassMessage() const {
1156 return getReceiverKind() == Class || getReceiverKind() == SuperClass;
1159 /// \brief Returns the receiver of an instance message.
1161 /// \brief Returns the object expression for an instance message, or
1162 /// NULL for a message that is not an instance message.
1163 Expr *getInstanceReceiver() {
1164 if (getReceiverKind() == Instance)
1165 return static_cast<Expr *>(getReceiverPointer());
1169 const Expr *getInstanceReceiver() const {
1170 return const_cast<ObjCMessageExpr*>(this)->getInstanceReceiver();
1173 /// \brief Turn this message send into an instance message that
1174 /// computes the receiver object with the given expression.
1175 void setInstanceReceiver(Expr *rec) {
1177 setReceiverPointer(rec);
1180 /// \brief Returns the type of a class message send, or NULL if the
1181 /// message is not a class message.
1182 QualType getClassReceiver() const {
1183 if (TypeSourceInfo *TSInfo = getClassReceiverTypeInfo())
1184 return TSInfo->getType();
1189 /// \brief Returns a type-source information of a class message
1190 /// send, or NULL if the message is not a class message.
1191 TypeSourceInfo *getClassReceiverTypeInfo() const {
1192 if (getReceiverKind() == Class)
1193 return reinterpret_cast<TypeSourceInfo *>(getReceiverPointer());
1197 void setClassReceiver(TypeSourceInfo *TSInfo) {
1199 setReceiverPointer(TSInfo);
1202 /// \brief Retrieve the location of the 'super' keyword for a class
1203 /// or instance message to 'super', otherwise an invalid source location.
1204 SourceLocation getSuperLoc() const {
1205 if (getReceiverKind() == SuperInstance || getReceiverKind() == SuperClass)
1208 return SourceLocation();
1211 /// \brief Retrieve the Objective-C interface to which this message
1212 /// is being directed, if known.
1214 /// This routine cross-cuts all of the different kinds of message
1215 /// sends to determine what the underlying (statically known) type
1216 /// of the receiver will be; use \c getReceiverKind() to determine
1217 /// whether the message is a class or an instance method, whether it
1218 /// is a send to super or not, etc.
1220 /// \returns The Objective-C interface if known, otherwise NULL.
1221 ObjCInterfaceDecl *getReceiverInterface() const;
1223 /// \brief Retrieve the type referred to by 'super'.
1225 /// The returned type will either be an ObjCInterfaceType (for an
1226 /// class message to super) or an ObjCObjectPointerType that refers
1227 /// to a class (for an instance message to super);
1228 QualType getSuperType() const {
1229 if (getReceiverKind() == SuperInstance || getReceiverKind() == SuperClass)
1230 return QualType::getFromOpaquePtr(getReceiverPointer());
1235 void setSuper(SourceLocation Loc, QualType T, bool IsInstanceSuper) {
1236 Kind = IsInstanceSuper? SuperInstance : SuperClass;
1238 setReceiverPointer(T.getAsOpaquePtr());
1241 Selector getSelector() const;
1243 void setSelector(Selector S) {
1245 SelectorOrMethod = reinterpret_cast<uintptr_t>(S.getAsOpaquePtr());
1248 const ObjCMethodDecl *getMethodDecl() const {
1250 return reinterpret_cast<const ObjCMethodDecl *>(SelectorOrMethod);
1255 ObjCMethodDecl *getMethodDecl() {
1257 return reinterpret_cast<ObjCMethodDecl *>(SelectorOrMethod);
1262 void setMethodDecl(ObjCMethodDecl *MD) {
1264 SelectorOrMethod = reinterpret_cast<uintptr_t>(MD);
1267 ObjCMethodFamily getMethodFamily() const {
1268 if (HasMethod) return getMethodDecl()->getMethodFamily();
1269 return getSelector().getMethodFamily();
1272 /// \brief Return the number of actual arguments in this message,
1273 /// not counting the receiver.
1274 unsigned getNumArgs() const { return NumArgs; }
1276 /// \brief Retrieve the arguments to this message, not including the
1279 return reinterpret_cast<Expr **>(this + 1) + 1;
1281 const Expr * const *getArgs() const {
1282 return reinterpret_cast<const Expr * const *>(this + 1) + 1;
1285 /// getArg - Return the specified argument.
1286 Expr *getArg(unsigned Arg) {
1287 assert(Arg < NumArgs && "Arg access out of range!");
1288 return cast<Expr>(getArgs()[Arg]);
1290 const Expr *getArg(unsigned Arg) const {
1291 assert(Arg < NumArgs && "Arg access out of range!");
1292 return cast<Expr>(getArgs()[Arg]);
1294 /// setArg - Set the specified argument.
1295 void setArg(unsigned Arg, Expr *ArgExpr) {
1296 assert(Arg < NumArgs && "Arg access out of range!");
1297 getArgs()[Arg] = ArgExpr;
1300 /// isDelegateInitCall - Answers whether this message send has been
1301 /// tagged as a "delegate init call", i.e. a call to a method in the
1302 /// -init family on self from within an -init method implementation.
1303 bool isDelegateInitCall() const { return IsDelegateInitCall; }
1304 void setDelegateInitCall(bool isDelegate) { IsDelegateInitCall = isDelegate; }
1306 SourceLocation getLeftLoc() const { return LBracLoc; }
1307 SourceLocation getRightLoc() const { return RBracLoc; }
1309 SourceLocation getSelectorStartLoc() const {
1311 return getLocStart();
1312 return getSelectorLoc(0);
1314 SourceLocation getSelectorLoc(unsigned Index) const {
1315 assert(Index < getNumSelectorLocs() && "Index out of range!");
1316 if (hasStandardSelLocs())
1317 return getStandardSelectorLoc(Index, getSelector(),
1318 getSelLocsKind() == SelLoc_StandardWithSpace,
1319 llvm::makeArrayRef(const_cast<Expr**>(getArgs()),
1322 return getStoredSelLocs()[Index];
1325 void getSelectorLocs(SmallVectorImpl<SourceLocation> &SelLocs) const;
1327 unsigned getNumSelectorLocs() const {
1330 Selector Sel = getSelector();
1331 if (Sel.isUnarySelector())
1333 return Sel.getNumArgs();
1336 void setSourceRange(SourceRange R) {
1337 LBracLoc = R.getBegin();
1338 RBracLoc = R.getEnd();
1340 SourceRange getSourceRange() const LLVM_READONLY {
1341 return SourceRange(LBracLoc, RBracLoc);
1344 static bool classof(const Stmt *T) {
1345 return T->getStmtClass() == ObjCMessageExprClass;
1347 static bool classof(const ObjCMessageExpr *) { return true; }
1350 child_range children();
1352 typedef ExprIterator arg_iterator;
1353 typedef ConstExprIterator const_arg_iterator;
1355 arg_iterator arg_begin() { return reinterpret_cast<Stmt **>(getArgs()); }
1356 arg_iterator arg_end() {
1357 return reinterpret_cast<Stmt **>(getArgs() + NumArgs);
1359 const_arg_iterator arg_begin() const {
1360 return reinterpret_cast<Stmt const * const*>(getArgs());
1362 const_arg_iterator arg_end() const {
1363 return reinterpret_cast<Stmt const * const*>(getArgs() + NumArgs);
1366 friend class ASTStmtReader;
1367 friend class ASTStmtWriter;
1370 /// ObjCIsaExpr - Represent X->isa and X.isa when X is an ObjC 'id' type.
1371 /// (similar in spirit to MemberExpr).
1372 class ObjCIsaExpr : public Expr {
1373 /// Base - the expression for the base object pointer.
1376 /// IsaMemberLoc - This is the location of the 'isa'.
1377 SourceLocation IsaMemberLoc;
1379 /// IsArrow - True if this is "X->F", false if this is "X.F".
1382 ObjCIsaExpr(Expr *base, bool isarrow, SourceLocation l, QualType ty)
1383 : Expr(ObjCIsaExprClass, ty, VK_LValue, OK_Ordinary,
1384 /*TypeDependent=*/false, base->isValueDependent(),
1385 base->isInstantiationDependent(),
1386 /*ContainsUnexpandedParameterPack=*/false),
1387 Base(base), IsaMemberLoc(l), IsArrow(isarrow) {}
1389 /// \brief Build an empty expression.
1390 explicit ObjCIsaExpr(EmptyShell Empty) : Expr(ObjCIsaExprClass, Empty) { }
1392 void setBase(Expr *E) { Base = E; }
1393 Expr *getBase() const { return cast<Expr>(Base); }
1395 bool isArrow() const { return IsArrow; }
1396 void setArrow(bool A) { IsArrow = A; }
1398 /// getMemberLoc - Return the location of the "member", in X->F, it is the
1399 /// location of 'F'.
1400 SourceLocation getIsaMemberLoc() const { return IsaMemberLoc; }
1401 void setIsaMemberLoc(SourceLocation L) { IsaMemberLoc = L; }
1403 SourceRange getSourceRange() const LLVM_READONLY {
1404 return SourceRange(getBase()->getLocStart(), IsaMemberLoc);
1407 SourceLocation getExprLoc() const LLVM_READONLY { return IsaMemberLoc; }
1409 static bool classof(const Stmt *T) {
1410 return T->getStmtClass() == ObjCIsaExprClass;
1412 static bool classof(const ObjCIsaExpr *) { return true; }
1415 child_range children() { return child_range(&Base, &Base+1); }
1419 /// ObjCIndirectCopyRestoreExpr - Represents the passing of a function
1420 /// argument by indirect copy-restore in ARC. This is used to support
1421 /// passing indirect arguments with the wrong lifetime, e.g. when
1422 /// passing the address of a __strong local variable to an 'out'
1423 /// parameter. This expression kind is only valid in an "argument"
1424 /// position to some sort of call expression.
1426 /// The parameter must have type 'pointer to T', and the argument must
1427 /// have type 'pointer to U', where T and U agree except possibly in
1428 /// qualification. If the argument value is null, then a null pointer
1429 /// is passed; otherwise it points to an object A, and:
1430 /// 1. A temporary object B of type T is initialized, either by
1431 /// zero-initialization (used when initializing an 'out' parameter)
1432 /// or copy-initialization (used when initializing an 'inout'
1434 /// 2. The address of the temporary is passed to the function.
1435 /// 3. If the call completes normally, A is move-assigned from B.
1436 /// 4. Finally, A is destroyed immediately.
1438 /// Currently 'T' must be a retainable object lifetime and must be
1439 /// __autoreleasing; this qualifier is ignored when initializing
1441 class ObjCIndirectCopyRestoreExpr : public Expr {
1444 // unsigned ObjCIndirectCopyRestoreBits.ShouldCopy : 1;
1446 friend class ASTReader;
1447 friend class ASTStmtReader;
1449 void setShouldCopy(bool shouldCopy) {
1450 ObjCIndirectCopyRestoreExprBits.ShouldCopy = shouldCopy;
1453 explicit ObjCIndirectCopyRestoreExpr(EmptyShell Empty)
1454 : Expr(ObjCIndirectCopyRestoreExprClass, Empty) { }
1457 ObjCIndirectCopyRestoreExpr(Expr *operand, QualType type, bool shouldCopy)
1458 : Expr(ObjCIndirectCopyRestoreExprClass, type, VK_LValue, OK_Ordinary,
1459 operand->isTypeDependent(), operand->isValueDependent(),
1460 operand->isInstantiationDependent(),
1461 operand->containsUnexpandedParameterPack()),
1463 setShouldCopy(shouldCopy);
1466 Expr *getSubExpr() { return cast<Expr>(Operand); }
1467 const Expr *getSubExpr() const { return cast<Expr>(Operand); }
1469 /// shouldCopy - True if we should do the 'copy' part of the
1470 /// copy-restore. If false, the temporary will be zero-initialized.
1471 bool shouldCopy() const { return ObjCIndirectCopyRestoreExprBits.ShouldCopy; }
1473 child_range children() { return child_range(&Operand, &Operand+1); }
1475 // Source locations are determined by the subexpression.
1476 SourceRange getSourceRange() const LLVM_READONLY {
1477 return Operand->getSourceRange();
1479 SourceLocation getExprLoc() const LLVM_READONLY {
1480 return getSubExpr()->getExprLoc();
1483 static bool classof(const Stmt *s) {
1484 return s->getStmtClass() == ObjCIndirectCopyRestoreExprClass;
1486 static bool classof(const ObjCIndirectCopyRestoreExpr *) { return true; }
1489 /// \brief An Objective-C "bridged" cast expression, which casts between
1490 /// Objective-C pointers and C pointers, transferring ownership in the process.
1493 /// NSString *str = (__bridge_transfer NSString *)CFCreateString();
1495 class ObjCBridgedCastExpr : public ExplicitCastExpr {
1496 SourceLocation LParenLoc;
1497 SourceLocation BridgeKeywordLoc;
1500 friend class ASTStmtReader;
1501 friend class ASTStmtWriter;
1504 ObjCBridgedCastExpr(SourceLocation LParenLoc, ObjCBridgeCastKind Kind,
1505 CastKind CK, SourceLocation BridgeKeywordLoc,
1506 TypeSourceInfo *TSInfo, Expr *Operand)
1507 : ExplicitCastExpr(ObjCBridgedCastExprClass, TSInfo->getType(), VK_RValue,
1508 CK, Operand, 0, TSInfo),
1509 LParenLoc(LParenLoc), BridgeKeywordLoc(BridgeKeywordLoc), Kind(Kind) { }
1511 /// \brief Construct an empty Objective-C bridged cast.
1512 explicit ObjCBridgedCastExpr(EmptyShell Shell)
1513 : ExplicitCastExpr(ObjCBridgedCastExprClass, Shell, 0) { }
1515 SourceLocation getLParenLoc() const { return LParenLoc; }
1517 /// \brief Determine which kind of bridge is being performed via this cast.
1518 ObjCBridgeCastKind getBridgeKind() const {
1519 return static_cast<ObjCBridgeCastKind>(Kind);
1522 /// \brief Retrieve the kind of bridge being performed as a string.
1523 StringRef getBridgeKindName() const;
1525 /// \brief The location of the bridge keyword.
1526 SourceLocation getBridgeKeywordLoc() const { return BridgeKeywordLoc; }
1528 SourceRange getSourceRange() const LLVM_READONLY {
1529 return SourceRange(LParenLoc, getSubExpr()->getLocEnd());
1532 static bool classof(const Stmt *T) {
1533 return T->getStmtClass() == ObjCBridgedCastExprClass;
1535 static bool classof(const ObjCBridgedCastExpr *) { return true; }
1539 } // end namespace clang