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 SourceLocation getLocStart() const LLVM_READONLY { return AtLoc; }
48 SourceLocation getLocEnd() const LLVM_READONLY { return String->getLocEnd(); }
50 static bool classof(const Stmt *T) {
51 return T->getStmtClass() == ObjCStringLiteralClass;
55 child_range children() { return child_range(&String, &String+1); }
58 /// ObjCBoolLiteralExpr - Objective-C Boolean Literal.
60 class ObjCBoolLiteralExpr : public Expr {
64 ObjCBoolLiteralExpr(bool val, QualType Ty, SourceLocation l) :
65 Expr(ObjCBoolLiteralExprClass, Ty, VK_RValue, OK_Ordinary, false, false,
66 false, false), Value(val), Loc(l) {}
68 explicit ObjCBoolLiteralExpr(EmptyShell Empty)
69 : Expr(ObjCBoolLiteralExprClass, Empty) { }
71 bool getValue() const { return Value; }
72 void setValue(bool V) { Value = V; }
74 SourceLocation getLocStart() const LLVM_READONLY { return Loc; }
75 SourceLocation getLocEnd() const LLVM_READONLY { return Loc; }
77 SourceLocation getLocation() const { return Loc; }
78 void setLocation(SourceLocation L) { Loc = L; }
80 static bool classof(const Stmt *T) {
81 return T->getStmtClass() == ObjCBoolLiteralExprClass;
85 child_range children() { return child_range(); }
88 /// ObjCBoxedExpr - used for generalized expression boxing.
89 /// as in: @(strdup("hello world")) or @(random())
90 /// Also used for boxing non-parenthesized numeric literals;
91 /// as in: @42 or \@true (c++/objc++) or \@__yes (c/objc).
92 class ObjCBoxedExpr : public Expr {
94 ObjCMethodDecl *BoxingMethod;
97 ObjCBoxedExpr(Expr *E, QualType T, ObjCMethodDecl *method,
99 : Expr(ObjCBoxedExprClass, T, VK_RValue, OK_Ordinary,
100 E->isTypeDependent(), E->isValueDependent(),
101 E->isInstantiationDependent(), E->containsUnexpandedParameterPack()),
102 SubExpr(E), BoxingMethod(method), Range(R) {}
103 explicit ObjCBoxedExpr(EmptyShell Empty)
104 : Expr(ObjCBoxedExprClass, Empty) {}
106 Expr *getSubExpr() { return cast<Expr>(SubExpr); }
107 const Expr *getSubExpr() const { return cast<Expr>(SubExpr); }
109 ObjCMethodDecl *getBoxingMethod() const {
113 SourceLocation getAtLoc() const { return Range.getBegin(); }
115 SourceLocation getLocStart() const LLVM_READONLY { return Range.getBegin(); }
116 SourceLocation getLocEnd() const LLVM_READONLY { return Range.getEnd(); }
117 SourceRange getSourceRange() const LLVM_READONLY {
121 static bool classof(const Stmt *T) {
122 return T->getStmtClass() == ObjCBoxedExprClass;
126 child_range children() { return child_range(&SubExpr, &SubExpr+1); }
128 friend class ASTStmtReader;
131 /// ObjCArrayLiteral - used for objective-c array containers; as in:
132 /// @[@"Hello", NSApp, [NSNumber numberWithInt:42]];
133 class ObjCArrayLiteral : public Expr {
134 unsigned NumElements;
136 ObjCMethodDecl *ArrayWithObjectsMethod;
138 ObjCArrayLiteral(ArrayRef<Expr *> Elements,
139 QualType T, ObjCMethodDecl * Method,
142 explicit ObjCArrayLiteral(EmptyShell Empty, unsigned NumElements)
143 : Expr(ObjCArrayLiteralClass, Empty), NumElements(NumElements) {}
146 static ObjCArrayLiteral *Create(const ASTContext &C,
147 ArrayRef<Expr *> Elements,
148 QualType T, ObjCMethodDecl * Method,
151 static ObjCArrayLiteral *CreateEmpty(const ASTContext &C,
152 unsigned NumElements);
154 SourceLocation getLocStart() const LLVM_READONLY { return Range.getBegin(); }
155 SourceLocation getLocEnd() const LLVM_READONLY { return Range.getEnd(); }
156 SourceRange getSourceRange() const LLVM_READONLY { return Range; }
158 static bool classof(const Stmt *T) {
159 return T->getStmtClass() == ObjCArrayLiteralClass;
162 /// \brief Retrieve elements of array of literals.
163 Expr **getElements() { return reinterpret_cast<Expr **>(this + 1); }
165 /// \brief Retrieve elements of array of literals.
166 const Expr * const *getElements() const {
167 return reinterpret_cast<const Expr * const*>(this + 1);
170 /// getNumElements - Return number of elements of objective-c array literal.
171 unsigned getNumElements() const { return NumElements; }
173 /// getExpr - Return the Expr at the specified index.
174 Expr *getElement(unsigned Index) {
175 assert((Index < NumElements) && "Arg access out of range!");
176 return cast<Expr>(getElements()[Index]);
178 const Expr *getElement(unsigned Index) const {
179 assert((Index < NumElements) && "Arg access out of range!");
180 return cast<Expr>(getElements()[Index]);
183 ObjCMethodDecl *getArrayWithObjectsMethod() const {
184 return ArrayWithObjectsMethod;
188 child_range children() {
189 return child_range((Stmt **)getElements(),
190 (Stmt **)getElements() + NumElements);
193 friend class ASTStmtReader;
196 /// \brief An element in an Objective-C dictionary literal.
198 struct ObjCDictionaryElement {
199 /// \brief The key for the dictionary element.
202 /// \brief The value of the dictionary element.
205 /// \brief The location of the ellipsis, if this is a pack expansion.
206 SourceLocation EllipsisLoc;
208 /// \brief The number of elements this pack expansion will expand to, if
209 /// this is a pack expansion and is known.
210 Optional<unsigned> NumExpansions;
212 /// \brief Determines whether this dictionary element is a pack expansion.
213 bool isPackExpansion() const { return EllipsisLoc.isValid(); }
215 } // end namespace clang
218 template <> struct isPodLike<clang::ObjCDictionaryElement> : std::true_type {};
222 /// ObjCDictionaryLiteral - AST node to represent objective-c dictionary
223 /// literals; as in: @{@"name" : NSUserName(), @"date" : [NSDate date] };
224 class ObjCDictionaryLiteral : public Expr {
225 /// \brief Key/value pair used to store the key and value of a given element.
227 /// Objects of this type are stored directly after the expression.
228 struct KeyValuePair {
233 /// \brief Data that describes an element that is a pack expansion, used if any
234 /// of the elements in the dictionary literal are pack expansions.
235 struct ExpansionData {
236 /// \brief The location of the ellipsis, if this element is a pack
238 SourceLocation EllipsisLoc;
240 /// \brief If non-zero, the number of elements that this pack
241 /// expansion will expand to (+1).
242 unsigned NumExpansionsPlusOne;
245 /// \brief The number of elements in this dictionary literal.
246 unsigned NumElements : 31;
248 /// \brief Determine whether this dictionary literal has any pack expansions.
250 /// If the dictionary literal has pack expansions, then there will
251 /// be an array of pack expansion data following the array of
252 /// key/value pairs, which provide the locations of the ellipses (if
253 /// any) and number of elements in the expansion (if known). If
254 /// there are no pack expansions, we optimize away this storage.
255 unsigned HasPackExpansions : 1;
258 ObjCMethodDecl *DictWithObjectsMethod;
260 ObjCDictionaryLiteral(ArrayRef<ObjCDictionaryElement> VK,
261 bool HasPackExpansions,
262 QualType T, ObjCMethodDecl *method,
265 explicit ObjCDictionaryLiteral(EmptyShell Empty, unsigned NumElements,
266 bool HasPackExpansions)
267 : Expr(ObjCDictionaryLiteralClass, Empty), NumElements(NumElements),
268 HasPackExpansions(HasPackExpansions) {}
270 KeyValuePair *getKeyValues() {
271 return reinterpret_cast<KeyValuePair *>(this + 1);
274 const KeyValuePair *getKeyValues() const {
275 return reinterpret_cast<const KeyValuePair *>(this + 1);
278 ExpansionData *getExpansionData() {
279 if (!HasPackExpansions)
282 return reinterpret_cast<ExpansionData *>(getKeyValues() + NumElements);
285 const ExpansionData *getExpansionData() const {
286 if (!HasPackExpansions)
289 return reinterpret_cast<const ExpansionData *>(getKeyValues()+NumElements);
293 static ObjCDictionaryLiteral *Create(const ASTContext &C,
294 ArrayRef<ObjCDictionaryElement> VK,
295 bool HasPackExpansions,
296 QualType T, ObjCMethodDecl *method,
299 static ObjCDictionaryLiteral *CreateEmpty(const ASTContext &C,
300 unsigned NumElements,
301 bool HasPackExpansions);
303 /// getNumElements - Return number of elements of objective-c dictionary
305 unsigned getNumElements() const { return NumElements; }
307 ObjCDictionaryElement getKeyValueElement(unsigned Index) const {
308 assert((Index < NumElements) && "Arg access out of range!");
309 const KeyValuePair &KV = getKeyValues()[Index];
310 ObjCDictionaryElement Result = { KV.Key, KV.Value, SourceLocation(), None };
311 if (HasPackExpansions) {
312 const ExpansionData &Expansion = getExpansionData()[Index];
313 Result.EllipsisLoc = Expansion.EllipsisLoc;
314 if (Expansion.NumExpansionsPlusOne > 0)
315 Result.NumExpansions = Expansion.NumExpansionsPlusOne - 1;
320 ObjCMethodDecl *getDictWithObjectsMethod() const
321 { return DictWithObjectsMethod; }
323 SourceLocation getLocStart() const LLVM_READONLY { return Range.getBegin(); }
324 SourceLocation getLocEnd() const LLVM_READONLY { return Range.getEnd(); }
325 SourceRange getSourceRange() const LLVM_READONLY { return Range; }
327 static bool classof(const Stmt *T) {
328 return T->getStmtClass() == ObjCDictionaryLiteralClass;
332 child_range children() {
333 // Note: we're taking advantage of the layout of the KeyValuePair struct
334 // here. If that struct changes, this code will need to change as well.
335 return child_range(reinterpret_cast<Stmt **>(this + 1),
336 reinterpret_cast<Stmt **>(this + 1) + NumElements * 2);
339 friend class ASTStmtReader;
340 friend class ASTStmtWriter;
344 /// ObjCEncodeExpr, used for \@encode in Objective-C. \@encode has the same
345 /// type and behavior as StringLiteral except that the string initializer is
346 /// obtained from ASTContext with the encoding type as an argument.
347 class ObjCEncodeExpr : public Expr {
348 TypeSourceInfo *EncodedType;
349 SourceLocation AtLoc, RParenLoc;
351 ObjCEncodeExpr(QualType T, TypeSourceInfo *EncodedType,
352 SourceLocation at, SourceLocation rp)
353 : Expr(ObjCEncodeExprClass, T, VK_LValue, OK_Ordinary,
354 EncodedType->getType()->isDependentType(),
355 EncodedType->getType()->isDependentType(),
356 EncodedType->getType()->isInstantiationDependentType(),
357 EncodedType->getType()->containsUnexpandedParameterPack()),
358 EncodedType(EncodedType), AtLoc(at), RParenLoc(rp) {}
360 explicit ObjCEncodeExpr(EmptyShell Empty) : Expr(ObjCEncodeExprClass, Empty){}
363 SourceLocation getAtLoc() const { return AtLoc; }
364 void setAtLoc(SourceLocation L) { AtLoc = L; }
365 SourceLocation getRParenLoc() const { return RParenLoc; }
366 void setRParenLoc(SourceLocation L) { RParenLoc = L; }
368 QualType getEncodedType() const { return EncodedType->getType(); }
370 TypeSourceInfo *getEncodedTypeSourceInfo() const { return EncodedType; }
371 void setEncodedTypeSourceInfo(TypeSourceInfo *EncType) {
372 EncodedType = EncType;
375 SourceLocation getLocStart() const LLVM_READONLY { return AtLoc; }
376 SourceLocation getLocEnd() const LLVM_READONLY { return RParenLoc; }
378 static bool classof(const Stmt *T) {
379 return T->getStmtClass() == ObjCEncodeExprClass;
383 child_range children() { return child_range(); }
386 /// ObjCSelectorExpr used for \@selector in Objective-C.
387 class ObjCSelectorExpr : public Expr {
389 SourceLocation AtLoc, RParenLoc;
391 ObjCSelectorExpr(QualType T, Selector selInfo,
392 SourceLocation at, SourceLocation rp)
393 : Expr(ObjCSelectorExprClass, T, VK_RValue, OK_Ordinary, false, false,
395 SelName(selInfo), AtLoc(at), RParenLoc(rp){}
396 explicit ObjCSelectorExpr(EmptyShell Empty)
397 : Expr(ObjCSelectorExprClass, Empty) {}
399 Selector getSelector() const { return SelName; }
400 void setSelector(Selector S) { SelName = S; }
402 SourceLocation getAtLoc() const { return AtLoc; }
403 SourceLocation getRParenLoc() const { return RParenLoc; }
404 void setAtLoc(SourceLocation L) { AtLoc = L; }
405 void setRParenLoc(SourceLocation L) { RParenLoc = L; }
407 SourceLocation getLocStart() const LLVM_READONLY { return AtLoc; }
408 SourceLocation getLocEnd() const LLVM_READONLY { return RParenLoc; }
410 /// getNumArgs - Return the number of actual arguments to this call.
411 unsigned getNumArgs() const { return SelName.getNumArgs(); }
413 static bool classof(const Stmt *T) {
414 return T->getStmtClass() == ObjCSelectorExprClass;
418 child_range children() { return child_range(); }
421 /// ObjCProtocolExpr used for protocol expression in Objective-C.
423 /// This is used as: \@protocol(foo), as in:
425 /// [obj conformsToProtocol:@protocol(foo)]
428 /// The return type is "Protocol*".
429 class ObjCProtocolExpr : public Expr {
430 ObjCProtocolDecl *TheProtocol;
431 SourceLocation AtLoc, ProtoLoc, RParenLoc;
433 ObjCProtocolExpr(QualType T, ObjCProtocolDecl *protocol,
434 SourceLocation at, SourceLocation protoLoc, SourceLocation rp)
435 : Expr(ObjCProtocolExprClass, T, VK_RValue, OK_Ordinary, false, false,
437 TheProtocol(protocol), AtLoc(at), ProtoLoc(protoLoc), RParenLoc(rp) {}
438 explicit ObjCProtocolExpr(EmptyShell Empty)
439 : Expr(ObjCProtocolExprClass, Empty) {}
441 ObjCProtocolDecl *getProtocol() const { return TheProtocol; }
442 void setProtocol(ObjCProtocolDecl *P) { TheProtocol = P; }
444 SourceLocation getProtocolIdLoc() const { return ProtoLoc; }
445 SourceLocation getAtLoc() const { return AtLoc; }
446 SourceLocation getRParenLoc() const { return RParenLoc; }
447 void setAtLoc(SourceLocation L) { AtLoc = L; }
448 void setRParenLoc(SourceLocation L) { RParenLoc = L; }
450 SourceLocation getLocStart() const LLVM_READONLY { return AtLoc; }
451 SourceLocation getLocEnd() const LLVM_READONLY { return RParenLoc; }
453 static bool classof(const Stmt *T) {
454 return T->getStmtClass() == ObjCProtocolExprClass;
458 child_range children() { return child_range(); }
460 friend class ASTStmtReader;
461 friend class ASTStmtWriter;
464 /// ObjCIvarRefExpr - A reference to an ObjC instance variable.
465 class ObjCIvarRefExpr : public Expr {
469 /// OpLoc - This is the location of '.' or '->'
470 SourceLocation OpLoc;
472 bool IsArrow:1; // True if this is "X->F", false if this is "X.F".
473 bool IsFreeIvar:1; // True if ivar reference has no base (self assumed).
476 ObjCIvarRefExpr(ObjCIvarDecl *d, QualType t,
477 SourceLocation l, SourceLocation oploc,
479 bool arrow = false, bool freeIvar = false) :
480 Expr(ObjCIvarRefExprClass, t, VK_LValue,
481 d->isBitField() ? OK_BitField : OK_Ordinary,
482 /*TypeDependent=*/false, base->isValueDependent(),
483 base->isInstantiationDependent(),
484 base->containsUnexpandedParameterPack()),
485 D(d), Base(base), Loc(l), OpLoc(oploc),
486 IsArrow(arrow), IsFreeIvar(freeIvar) {}
488 explicit ObjCIvarRefExpr(EmptyShell Empty)
489 : Expr(ObjCIvarRefExprClass, Empty) {}
491 ObjCIvarDecl *getDecl() { return D; }
492 const ObjCIvarDecl *getDecl() const { return D; }
493 void setDecl(ObjCIvarDecl *d) { D = d; }
495 const Expr *getBase() const { return cast<Expr>(Base); }
496 Expr *getBase() { return cast<Expr>(Base); }
497 void setBase(Expr * base) { Base = base; }
499 bool isArrow() const { return IsArrow; }
500 bool isFreeIvar() const { return IsFreeIvar; }
501 void setIsArrow(bool A) { IsArrow = A; }
502 void setIsFreeIvar(bool A) { IsFreeIvar = A; }
504 SourceLocation getLocation() const { return Loc; }
505 void setLocation(SourceLocation L) { Loc = L; }
507 SourceLocation getLocStart() const LLVM_READONLY {
508 return isFreeIvar() ? Loc : getBase()->getLocStart();
510 SourceLocation getLocEnd() const LLVM_READONLY { return Loc; }
512 SourceLocation getOpLoc() const { return OpLoc; }
513 void setOpLoc(SourceLocation L) { OpLoc = L; }
515 static bool classof(const Stmt *T) {
516 return T->getStmtClass() == ObjCIvarRefExprClass;
520 child_range children() { return child_range(&Base, &Base+1); }
523 /// ObjCPropertyRefExpr - A dot-syntax expression to access an ObjC
525 class ObjCPropertyRefExpr : public Expr {
527 /// If the bool is true, this is an implicit property reference; the
528 /// pointer is an (optional) ObjCMethodDecl and Setter may be set.
529 /// if the bool is false, this is an explicit property reference;
530 /// the pointer is an ObjCPropertyDecl and Setter is always null.
531 llvm::PointerIntPair<NamedDecl*, 1, bool> PropertyOrGetter;
533 /// \brief Indicates whether the property reference will result in a message
534 /// to the getter, the setter, or both.
535 /// This applies to both implicit and explicit property references.
536 enum MethodRefFlags {
538 MethodRef_Getter = 0x1,
539 MethodRef_Setter = 0x2
542 /// \brief Contains the Setter method pointer and MethodRefFlags bit flags.
543 llvm::PointerIntPair<ObjCMethodDecl *, 2, unsigned> SetterAndMethodRefFlags;
545 // FIXME: Maybe we should store the property identifier here,
546 // because it's not rederivable from the other data when there's an
547 // implicit property with no getter (because the 'foo' -> 'setFoo:'
548 // transformation is lossy on the first character).
550 SourceLocation IdLoc;
552 /// \brief When the receiver in property access is 'super', this is
553 /// the location of the 'super' keyword. When it's an interface,
554 /// this is that interface.
555 SourceLocation ReceiverLoc;
556 llvm::PointerUnion3<Stmt*, const Type*, ObjCInterfaceDecl*> Receiver;
559 ObjCPropertyRefExpr(ObjCPropertyDecl *PD, QualType t,
560 ExprValueKind VK, ExprObjectKind OK,
561 SourceLocation l, Expr *base)
562 : Expr(ObjCPropertyRefExprClass, t, VK, OK,
563 /*TypeDependent=*/false, base->isValueDependent(),
564 base->isInstantiationDependent(),
565 base->containsUnexpandedParameterPack()),
566 PropertyOrGetter(PD, false), SetterAndMethodRefFlags(),
567 IdLoc(l), ReceiverLoc(), Receiver(base) {
568 assert(t->isSpecificPlaceholderType(BuiltinType::PseudoObject));
571 ObjCPropertyRefExpr(ObjCPropertyDecl *PD, QualType t,
572 ExprValueKind VK, ExprObjectKind OK,
573 SourceLocation l, SourceLocation sl, QualType st)
574 : Expr(ObjCPropertyRefExprClass, t, VK, OK,
575 /*TypeDependent=*/false, false, st->isInstantiationDependentType(),
576 st->containsUnexpandedParameterPack()),
577 PropertyOrGetter(PD, false), SetterAndMethodRefFlags(),
578 IdLoc(l), ReceiverLoc(sl), Receiver(st.getTypePtr()) {
579 assert(t->isSpecificPlaceholderType(BuiltinType::PseudoObject));
582 ObjCPropertyRefExpr(ObjCMethodDecl *Getter, ObjCMethodDecl *Setter,
583 QualType T, ExprValueKind VK, ExprObjectKind OK,
584 SourceLocation IdLoc, Expr *Base)
585 : Expr(ObjCPropertyRefExprClass, T, VK, OK, false,
586 Base->isValueDependent(), Base->isInstantiationDependent(),
587 Base->containsUnexpandedParameterPack()),
588 PropertyOrGetter(Getter, true), SetterAndMethodRefFlags(Setter, 0),
589 IdLoc(IdLoc), ReceiverLoc(), Receiver(Base) {
590 assert(T->isSpecificPlaceholderType(BuiltinType::PseudoObject));
593 ObjCPropertyRefExpr(ObjCMethodDecl *Getter, ObjCMethodDecl *Setter,
594 QualType T, ExprValueKind VK, ExprObjectKind OK,
595 SourceLocation IdLoc,
596 SourceLocation SuperLoc, QualType SuperTy)
597 : Expr(ObjCPropertyRefExprClass, T, VK, OK, false, false, false, false),
598 PropertyOrGetter(Getter, true), SetterAndMethodRefFlags(Setter, 0),
599 IdLoc(IdLoc), ReceiverLoc(SuperLoc), Receiver(SuperTy.getTypePtr()) {
600 assert(T->isSpecificPlaceholderType(BuiltinType::PseudoObject));
603 ObjCPropertyRefExpr(ObjCMethodDecl *Getter, ObjCMethodDecl *Setter,
604 QualType T, ExprValueKind VK, ExprObjectKind OK,
605 SourceLocation IdLoc,
606 SourceLocation ReceiverLoc, ObjCInterfaceDecl *Receiver)
607 : Expr(ObjCPropertyRefExprClass, T, VK, OK, false, false, false, false),
608 PropertyOrGetter(Getter, true), SetterAndMethodRefFlags(Setter, 0),
609 IdLoc(IdLoc), ReceiverLoc(ReceiverLoc), Receiver(Receiver) {
610 assert(T->isSpecificPlaceholderType(BuiltinType::PseudoObject));
613 explicit ObjCPropertyRefExpr(EmptyShell Empty)
614 : Expr(ObjCPropertyRefExprClass, Empty) {}
616 bool isImplicitProperty() const { return PropertyOrGetter.getInt(); }
617 bool isExplicitProperty() const { return !PropertyOrGetter.getInt(); }
619 ObjCPropertyDecl *getExplicitProperty() const {
620 assert(!isImplicitProperty());
621 return cast<ObjCPropertyDecl>(PropertyOrGetter.getPointer());
624 ObjCMethodDecl *getImplicitPropertyGetter() const {
625 assert(isImplicitProperty());
626 return cast_or_null<ObjCMethodDecl>(PropertyOrGetter.getPointer());
629 ObjCMethodDecl *getImplicitPropertySetter() const {
630 assert(isImplicitProperty());
631 return SetterAndMethodRefFlags.getPointer();
634 Selector getGetterSelector() const {
635 if (isImplicitProperty())
636 return getImplicitPropertyGetter()->getSelector();
637 return getExplicitProperty()->getGetterName();
640 Selector getSetterSelector() const {
641 if (isImplicitProperty())
642 return getImplicitPropertySetter()->getSelector();
643 return getExplicitProperty()->getSetterName();
646 /// \brief True if the property reference will result in a message to the
648 /// This applies to both implicit and explicit property references.
649 bool isMessagingGetter() const {
650 return SetterAndMethodRefFlags.getInt() & MethodRef_Getter;
653 /// \brief True if the property reference will result in a message to the
655 /// This applies to both implicit and explicit property references.
656 bool isMessagingSetter() const {
657 return SetterAndMethodRefFlags.getInt() & MethodRef_Setter;
660 void setIsMessagingGetter(bool val = true) {
661 setMethodRefFlag(MethodRef_Getter, val);
664 void setIsMessagingSetter(bool val = true) {
665 setMethodRefFlag(MethodRef_Setter, val);
668 const Expr *getBase() const {
669 return cast<Expr>(Receiver.get<Stmt*>());
672 return cast<Expr>(Receiver.get<Stmt*>());
675 SourceLocation getLocation() const { return IdLoc; }
677 SourceLocation getReceiverLocation() const { return ReceiverLoc; }
678 QualType getSuperReceiverType() const {
679 return QualType(Receiver.get<const Type*>(), 0);
681 QualType getGetterResultType() const {
683 if (isExplicitProperty()) {
684 const ObjCPropertyDecl *PDecl = getExplicitProperty();
685 if (const ObjCMethodDecl *Getter = PDecl->getGetterMethodDecl())
686 ResultType = Getter->getReturnType();
688 ResultType = PDecl->getType();
690 const ObjCMethodDecl *Getter = getImplicitPropertyGetter();
692 ResultType = Getter->getReturnType(); // with reference!
697 QualType getSetterArgType() const {
699 if (isImplicitProperty()) {
700 const ObjCMethodDecl *Setter = getImplicitPropertySetter();
701 ObjCMethodDecl::param_const_iterator P = Setter->param_begin();
702 ArgType = (*P)->getType();
704 if (ObjCPropertyDecl *PDecl = getExplicitProperty())
705 if (const ObjCMethodDecl *Setter = PDecl->getSetterMethodDecl()) {
706 ObjCMethodDecl::param_const_iterator P = Setter->param_begin();
707 ArgType = (*P)->getType();
709 if (ArgType.isNull())
715 ObjCInterfaceDecl *getClassReceiver() const {
716 return Receiver.get<ObjCInterfaceDecl*>();
718 bool isObjectReceiver() const { return Receiver.is<Stmt*>(); }
719 bool isSuperReceiver() const { return Receiver.is<const Type*>(); }
720 bool isClassReceiver() const { return Receiver.is<ObjCInterfaceDecl*>(); }
722 SourceLocation getLocStart() const LLVM_READONLY {
723 return isObjectReceiver() ? getBase()->getLocStart() :getReceiverLocation();
725 SourceLocation getLocEnd() const LLVM_READONLY { return IdLoc; }
727 static bool classof(const Stmt *T) {
728 return T->getStmtClass() == ObjCPropertyRefExprClass;
732 child_range children() {
733 if (Receiver.is<Stmt*>()) {
734 Stmt **begin = reinterpret_cast<Stmt**>(&Receiver); // hack!
735 return child_range(begin, begin+1);
737 return child_range();
741 friend class ASTStmtReader;
742 friend class ASTStmtWriter;
743 void setExplicitProperty(ObjCPropertyDecl *D, unsigned methRefFlags) {
744 PropertyOrGetter.setPointer(D);
745 PropertyOrGetter.setInt(false);
746 SetterAndMethodRefFlags.setPointer(nullptr);
747 SetterAndMethodRefFlags.setInt(methRefFlags);
749 void setImplicitProperty(ObjCMethodDecl *Getter, ObjCMethodDecl *Setter,
750 unsigned methRefFlags) {
751 PropertyOrGetter.setPointer(Getter);
752 PropertyOrGetter.setInt(true);
753 SetterAndMethodRefFlags.setPointer(Setter);
754 SetterAndMethodRefFlags.setInt(methRefFlags);
756 void setBase(Expr *Base) { Receiver = Base; }
757 void setSuperReceiver(QualType T) { Receiver = T.getTypePtr(); }
758 void setClassReceiver(ObjCInterfaceDecl *D) { Receiver = D; }
760 void setLocation(SourceLocation L) { IdLoc = L; }
761 void setReceiverLocation(SourceLocation Loc) { ReceiverLoc = Loc; }
763 void setMethodRefFlag(MethodRefFlags flag, bool val) {
764 unsigned f = SetterAndMethodRefFlags.getInt();
769 SetterAndMethodRefFlags.setInt(f);
773 /// ObjCSubscriptRefExpr - used for array and dictionary subscripting.
774 /// array[4] = array[3]; dictionary[key] = dictionary[alt_key];
776 class ObjCSubscriptRefExpr : public Expr {
777 // Location of ']' in an indexing expression.
778 SourceLocation RBracket;
779 // array/dictionary base expression.
780 // for arrays, this is a numeric expression. For dictionaries, this is
781 // an objective-c object pointer expression.
782 enum { BASE, KEY, END_EXPR };
783 Stmt* SubExprs[END_EXPR];
785 ObjCMethodDecl *GetAtIndexMethodDecl;
787 // For immutable objects this is null. When ObjCSubscriptRefExpr is to read
788 // an indexed object this is null too.
789 ObjCMethodDecl *SetAtIndexMethodDecl;
793 ObjCSubscriptRefExpr(Expr *base, Expr *key, QualType T,
794 ExprValueKind VK, ExprObjectKind OK,
795 ObjCMethodDecl *getMethod,
796 ObjCMethodDecl *setMethod, SourceLocation RB)
797 : Expr(ObjCSubscriptRefExprClass, T, VK, OK,
798 base->isTypeDependent() || key->isTypeDependent(),
799 base->isValueDependent() || key->isValueDependent(),
800 base->isInstantiationDependent() || key->isInstantiationDependent(),
801 (base->containsUnexpandedParameterPack() ||
802 key->containsUnexpandedParameterPack())),
804 GetAtIndexMethodDecl(getMethod),
805 SetAtIndexMethodDecl(setMethod)
806 {SubExprs[BASE] = base; SubExprs[KEY] = key;}
808 explicit ObjCSubscriptRefExpr(EmptyShell Empty)
809 : Expr(ObjCSubscriptRefExprClass, Empty) {}
811 static ObjCSubscriptRefExpr *Create(const ASTContext &C,
813 Expr *key, QualType T,
814 ObjCMethodDecl *getMethod,
815 ObjCMethodDecl *setMethod,
818 SourceLocation getRBracket() const { return RBracket; }
819 void setRBracket(SourceLocation RB) { RBracket = RB; }
821 SourceLocation getLocStart() const LLVM_READONLY {
822 return SubExprs[BASE]->getLocStart();
824 SourceLocation getLocEnd() const LLVM_READONLY { return RBracket; }
826 static bool classof(const Stmt *T) {
827 return T->getStmtClass() == ObjCSubscriptRefExprClass;
830 Expr *getBaseExpr() const { return cast<Expr>(SubExprs[BASE]); }
831 void setBaseExpr(Stmt *S) { SubExprs[BASE] = S; }
833 Expr *getKeyExpr() const { return cast<Expr>(SubExprs[KEY]); }
834 void setKeyExpr(Stmt *S) { SubExprs[KEY] = S; }
836 ObjCMethodDecl *getAtIndexMethodDecl() const {
837 return GetAtIndexMethodDecl;
840 ObjCMethodDecl *setAtIndexMethodDecl() const {
841 return SetAtIndexMethodDecl;
844 bool isArraySubscriptRefExpr() const {
845 return getKeyExpr()->getType()->isIntegralOrEnumerationType();
848 child_range children() {
849 return child_range(SubExprs, SubExprs+END_EXPR);
852 friend class ASTStmtReader;
856 /// \brief An expression that sends a message to the given Objective-C
859 /// The following contains two message send expressions:
862 /// [[NSString alloc] initWithString:@"Hello"]
865 /// The innermost message send invokes the "alloc" class method on the
866 /// NSString class, while the outermost message send invokes the
867 /// "initWithString" instance method on the object returned from
868 /// NSString's "alloc". In all, an Objective-C message send can take
869 /// on four different (although related) forms:
871 /// 1. Send to an object instance.
872 /// 2. Send to a class.
873 /// 3. Send to the superclass instance of the current class.
874 /// 4. Send to the superclass of the current class.
876 /// All four kinds of message sends are modeled by the ObjCMessageExpr
877 /// class, and can be distinguished via \c getReceiverKind(). Example:
879 class ObjCMessageExpr : public Expr {
880 /// \brief Stores either the selector that this message is sending
881 /// to (when \c HasMethod is zero) or an \c ObjCMethodDecl pointer
882 /// referring to the method that we type-checked against.
883 uintptr_t SelectorOrMethod;
885 enum { NumArgsBitWidth = 16 };
887 /// \brief The number of arguments in the message send, not
888 /// including the receiver.
889 unsigned NumArgs : NumArgsBitWidth;
891 void setNumArgs(unsigned Num) {
892 assert((Num >> NumArgsBitWidth) == 0 && "Num of args is out of range!");
896 /// \brief The kind of message send this is, which is one of the
897 /// ReceiverKind values.
899 /// We pad this out to a byte to avoid excessive masking and shifting.
902 /// \brief Whether we have an actual method prototype in \c
903 /// SelectorOrMethod.
905 /// When non-zero, we have a method declaration; otherwise, we just
907 unsigned HasMethod : 1;
909 /// \brief Whether this message send is a "delegate init call",
910 /// i.e. a call of an init method on self from within an init method.
911 unsigned IsDelegateInitCall : 1;
913 /// \brief Whether this message send was implicitly generated by
914 /// the implementation rather than explicitly written by the user.
915 unsigned IsImplicit : 1;
917 /// \brief Whether the locations of the selector identifiers are in a
918 /// "standard" position, a enum SelectorLocationsKind.
919 unsigned SelLocsKind : 2;
921 /// \brief When the message expression is a send to 'super', this is
922 /// the location of the 'super' keyword.
923 SourceLocation SuperLoc;
925 /// \brief The source locations of the open and close square
926 /// brackets ('[' and ']', respectively).
927 SourceLocation LBracLoc, RBracLoc;
929 ObjCMessageExpr(EmptyShell Empty, unsigned NumArgs)
930 : Expr(ObjCMessageExprClass, Empty), SelectorOrMethod(0), Kind(0),
931 HasMethod(0), IsDelegateInitCall(0), IsImplicit(0), SelLocsKind(0) {
935 ObjCMessageExpr(QualType T, ExprValueKind VK,
936 SourceLocation LBracLoc,
937 SourceLocation SuperLoc,
938 bool IsInstanceSuper,
941 ArrayRef<SourceLocation> SelLocs,
942 SelectorLocationsKind SelLocsK,
943 ObjCMethodDecl *Method,
944 ArrayRef<Expr *> Args,
945 SourceLocation RBracLoc,
947 ObjCMessageExpr(QualType T, ExprValueKind VK,
948 SourceLocation LBracLoc,
949 TypeSourceInfo *Receiver,
951 ArrayRef<SourceLocation> SelLocs,
952 SelectorLocationsKind SelLocsK,
953 ObjCMethodDecl *Method,
954 ArrayRef<Expr *> Args,
955 SourceLocation RBracLoc,
957 ObjCMessageExpr(QualType T, ExprValueKind VK,
958 SourceLocation LBracLoc,
961 ArrayRef<SourceLocation> SelLocs,
962 SelectorLocationsKind SelLocsK,
963 ObjCMethodDecl *Method,
964 ArrayRef<Expr *> Args,
965 SourceLocation RBracLoc,
968 void initArgsAndSelLocs(ArrayRef<Expr *> Args,
969 ArrayRef<SourceLocation> SelLocs,
970 SelectorLocationsKind SelLocsK);
972 /// \brief Retrieve the pointer value of the message receiver.
973 void *getReceiverPointer() const {
974 return *const_cast<void **>(
975 reinterpret_cast<const void * const*>(this + 1));
978 /// \brief Set the pointer value of the message receiver.
979 void setReceiverPointer(void *Value) {
980 *reinterpret_cast<void **>(this + 1) = Value;
983 SelectorLocationsKind getSelLocsKind() const {
984 return (SelectorLocationsKind)SelLocsKind;
986 bool hasStandardSelLocs() const {
987 return getSelLocsKind() != SelLoc_NonStandard;
990 /// \brief Get a pointer to the stored selector identifiers locations array.
991 /// No locations will be stored if HasStandardSelLocs is true.
992 SourceLocation *getStoredSelLocs() {
993 return reinterpret_cast<SourceLocation*>(getArgs() + getNumArgs());
995 const SourceLocation *getStoredSelLocs() const {
996 return reinterpret_cast<const SourceLocation*>(getArgs() + getNumArgs());
999 /// \brief Get the number of stored selector identifiers locations.
1000 /// No locations will be stored if HasStandardSelLocs is true.
1001 unsigned getNumStoredSelLocs() const {
1002 if (hasStandardSelLocs())
1004 return getNumSelectorLocs();
1007 static ObjCMessageExpr *alloc(const ASTContext &C,
1008 ArrayRef<Expr *> Args,
1009 SourceLocation RBraceLoc,
1010 ArrayRef<SourceLocation> SelLocs,
1012 SelectorLocationsKind &SelLocsK);
1013 static ObjCMessageExpr *alloc(const ASTContext &C,
1015 unsigned NumStoredSelLocs);
1018 /// \brief The kind of receiver this message is sending to.
1020 /// \brief The receiver is a class.
1022 /// \brief The receiver is an object instance.
1024 /// \brief The receiver is a superclass.
1026 /// \brief The receiver is the instance of the superclass object.
1030 /// \brief Create a message send to super.
1032 /// \param Context The ASTContext in which this expression will be created.
1034 /// \param T The result type of this message.
1036 /// \param VK The value kind of this message. A message returning
1037 /// a l-value or r-value reference will be an l-value or x-value,
1040 /// \param LBracLoc The location of the open square bracket '['.
1042 /// \param SuperLoc The location of the "super" keyword.
1044 /// \param IsInstanceSuper Whether this is an instance "super"
1045 /// message (otherwise, it's a class "super" message).
1047 /// \param Sel The selector used to determine which method gets called.
1049 /// \param Method The Objective-C method against which this message
1050 /// send was type-checked. May be NULL.
1052 /// \param Args The message send arguments.
1054 /// \param RBracLoc The location of the closing square bracket ']'.
1055 static ObjCMessageExpr *Create(const ASTContext &Context, QualType T,
1057 SourceLocation LBracLoc,
1058 SourceLocation SuperLoc,
1059 bool IsInstanceSuper,
1062 ArrayRef<SourceLocation> SelLocs,
1063 ObjCMethodDecl *Method,
1064 ArrayRef<Expr *> Args,
1065 SourceLocation RBracLoc,
1068 /// \brief Create a class message send.
1070 /// \param Context The ASTContext in which this expression will be created.
1072 /// \param T The result type of this message.
1074 /// \param VK The value kind of this message. A message returning
1075 /// a l-value or r-value reference will be an l-value or x-value,
1078 /// \param LBracLoc The location of the open square bracket '['.
1080 /// \param Receiver The type of the receiver, including
1081 /// source-location information.
1083 /// \param Sel The selector used to determine which method gets called.
1085 /// \param Method The Objective-C method against which this message
1086 /// send was type-checked. May be NULL.
1088 /// \param Args The message send arguments.
1090 /// \param RBracLoc The location of the closing square bracket ']'.
1091 static ObjCMessageExpr *Create(const ASTContext &Context, QualType T,
1093 SourceLocation LBracLoc,
1094 TypeSourceInfo *Receiver,
1096 ArrayRef<SourceLocation> SelLocs,
1097 ObjCMethodDecl *Method,
1098 ArrayRef<Expr *> Args,
1099 SourceLocation RBracLoc,
1102 /// \brief Create an instance message send.
1104 /// \param Context The ASTContext in which this expression will be created.
1106 /// \param T The result type of this message.
1108 /// \param VK The value kind of this message. A message returning
1109 /// a l-value or r-value reference will be an l-value or x-value,
1112 /// \param LBracLoc The location of the open square bracket '['.
1114 /// \param Receiver The expression used to produce the object that
1115 /// will receive this message.
1117 /// \param Sel The selector used to determine which method gets called.
1119 /// \param Method The Objective-C method against which this message
1120 /// send was type-checked. May be NULL.
1122 /// \param Args The message send arguments.
1124 /// \param RBracLoc The location of the closing square bracket ']'.
1125 static ObjCMessageExpr *Create(const ASTContext &Context, QualType T,
1127 SourceLocation LBracLoc,
1130 ArrayRef<SourceLocation> SeLocs,
1131 ObjCMethodDecl *Method,
1132 ArrayRef<Expr *> Args,
1133 SourceLocation RBracLoc,
1136 /// \brief Create an empty Objective-C message expression, to be
1137 /// filled in by subsequent calls.
1139 /// \param Context The context in which the message send will be created.
1141 /// \param NumArgs The number of message arguments, not including
1143 static ObjCMessageExpr *CreateEmpty(const ASTContext &Context,
1145 unsigned NumStoredSelLocs);
1147 /// \brief Indicates whether the message send was implicitly
1148 /// generated by the implementation. If false, it was written explicitly
1149 /// in the source code.
1150 bool isImplicit() const { return IsImplicit; }
1152 /// \brief Determine the kind of receiver that this message is being
1154 ReceiverKind getReceiverKind() const { return (ReceiverKind)Kind; }
1156 /// \brief Source range of the receiver.
1157 SourceRange getReceiverRange() const;
1159 /// \brief Determine whether this is an instance message to either a
1160 /// computed object or to super.
1161 bool isInstanceMessage() const {
1162 return getReceiverKind() == Instance || getReceiverKind() == SuperInstance;
1165 /// \brief Determine whether this is an class message to either a
1166 /// specified class or to super.
1167 bool isClassMessage() const {
1168 return getReceiverKind() == Class || getReceiverKind() == SuperClass;
1171 /// \brief Returns the object expression (receiver) for an instance message,
1172 /// or null for a message that is not an instance message.
1173 Expr *getInstanceReceiver() {
1174 if (getReceiverKind() == Instance)
1175 return static_cast<Expr *>(getReceiverPointer());
1179 const Expr *getInstanceReceiver() const {
1180 return const_cast<ObjCMessageExpr*>(this)->getInstanceReceiver();
1183 /// \brief Turn this message send into an instance message that
1184 /// computes the receiver object with the given expression.
1185 void setInstanceReceiver(Expr *rec) {
1187 setReceiverPointer(rec);
1190 /// \brief Returns the type of a class message send, or NULL if the
1191 /// message is not a class message.
1192 QualType getClassReceiver() const {
1193 if (TypeSourceInfo *TSInfo = getClassReceiverTypeInfo())
1194 return TSInfo->getType();
1199 /// \brief Returns a type-source information of a class message
1200 /// send, or NULL if the message is not a class message.
1201 TypeSourceInfo *getClassReceiverTypeInfo() const {
1202 if (getReceiverKind() == Class)
1203 return reinterpret_cast<TypeSourceInfo *>(getReceiverPointer());
1207 void setClassReceiver(TypeSourceInfo *TSInfo) {
1209 setReceiverPointer(TSInfo);
1212 /// \brief Retrieve the location of the 'super' keyword for a class
1213 /// or instance message to 'super', otherwise an invalid source location.
1214 SourceLocation getSuperLoc() const {
1215 if (getReceiverKind() == SuperInstance || getReceiverKind() == SuperClass)
1218 return SourceLocation();
1221 /// \brief Retrieve the receiver type to which this message is being directed.
1223 /// This routine cross-cuts all of the different kinds of message
1224 /// sends to determine what the underlying (statically known) type
1225 /// of the receiver will be; use \c getReceiverKind() to determine
1226 /// whether the message is a class or an instance method, whether it
1227 /// is a send to super or not, etc.
1229 /// \returns The type of the receiver.
1230 QualType getReceiverType() const;
1232 /// \brief Retrieve the Objective-C interface to which this message
1233 /// is being directed, if known.
1235 /// This routine cross-cuts all of the different kinds of message
1236 /// sends to determine what the underlying (statically known) type
1237 /// of the receiver will be; use \c getReceiverKind() to determine
1238 /// whether the message is a class or an instance method, whether it
1239 /// is a send to super or not, etc.
1241 /// \returns The Objective-C interface if known, otherwise NULL.
1242 ObjCInterfaceDecl *getReceiverInterface() const;
1244 /// \brief Retrieve the type referred to by 'super'.
1246 /// The returned type will either be an ObjCInterfaceType (for an
1247 /// class message to super) or an ObjCObjectPointerType that refers
1248 /// to a class (for an instance message to super);
1249 QualType getSuperType() const {
1250 if (getReceiverKind() == SuperInstance || getReceiverKind() == SuperClass)
1251 return QualType::getFromOpaquePtr(getReceiverPointer());
1256 void setSuper(SourceLocation Loc, QualType T, bool IsInstanceSuper) {
1257 Kind = IsInstanceSuper? SuperInstance : SuperClass;
1259 setReceiverPointer(T.getAsOpaquePtr());
1262 Selector getSelector() const;
1264 void setSelector(Selector S) {
1266 SelectorOrMethod = reinterpret_cast<uintptr_t>(S.getAsOpaquePtr());
1269 const ObjCMethodDecl *getMethodDecl() const {
1271 return reinterpret_cast<const ObjCMethodDecl *>(SelectorOrMethod);
1276 ObjCMethodDecl *getMethodDecl() {
1278 return reinterpret_cast<ObjCMethodDecl *>(SelectorOrMethod);
1283 void setMethodDecl(ObjCMethodDecl *MD) {
1285 SelectorOrMethod = reinterpret_cast<uintptr_t>(MD);
1288 ObjCMethodFamily getMethodFamily() const {
1289 if (HasMethod) return getMethodDecl()->getMethodFamily();
1290 return getSelector().getMethodFamily();
1293 /// \brief Return the number of actual arguments in this message,
1294 /// not counting the receiver.
1295 unsigned getNumArgs() const { return NumArgs; }
1297 /// \brief Retrieve the arguments to this message, not including the
1300 return reinterpret_cast<Expr **>(this + 1) + 1;
1302 const Expr * const *getArgs() const {
1303 return reinterpret_cast<const Expr * const *>(this + 1) + 1;
1306 /// getArg - Return the specified argument.
1307 Expr *getArg(unsigned Arg) {
1308 assert(Arg < NumArgs && "Arg access out of range!");
1309 return cast<Expr>(getArgs()[Arg]);
1311 const Expr *getArg(unsigned Arg) const {
1312 assert(Arg < NumArgs && "Arg access out of range!");
1313 return cast<Expr>(getArgs()[Arg]);
1315 /// setArg - Set the specified argument.
1316 void setArg(unsigned Arg, Expr *ArgExpr) {
1317 assert(Arg < NumArgs && "Arg access out of range!");
1318 getArgs()[Arg] = ArgExpr;
1321 /// isDelegateInitCall - Answers whether this message send has been
1322 /// tagged as a "delegate init call", i.e. a call to a method in the
1323 /// -init family on self from within an -init method implementation.
1324 bool isDelegateInitCall() const { return IsDelegateInitCall; }
1325 void setDelegateInitCall(bool isDelegate) { IsDelegateInitCall = isDelegate; }
1327 SourceLocation getLeftLoc() const { return LBracLoc; }
1328 SourceLocation getRightLoc() const { return RBracLoc; }
1330 SourceLocation getSelectorStartLoc() const {
1332 return getLocStart();
1333 return getSelectorLoc(0);
1335 SourceLocation getSelectorLoc(unsigned Index) const {
1336 assert(Index < getNumSelectorLocs() && "Index out of range!");
1337 if (hasStandardSelLocs())
1338 return getStandardSelectorLoc(Index, getSelector(),
1339 getSelLocsKind() == SelLoc_StandardWithSpace,
1340 llvm::makeArrayRef(const_cast<Expr**>(getArgs()),
1343 return getStoredSelLocs()[Index];
1346 void getSelectorLocs(SmallVectorImpl<SourceLocation> &SelLocs) const;
1348 unsigned getNumSelectorLocs() const {
1351 Selector Sel = getSelector();
1352 if (Sel.isUnarySelector())
1354 return Sel.getNumArgs();
1357 void setSourceRange(SourceRange R) {
1358 LBracLoc = R.getBegin();
1359 RBracLoc = R.getEnd();
1361 SourceLocation getLocStart() const LLVM_READONLY { return LBracLoc; }
1362 SourceLocation getLocEnd() const LLVM_READONLY { return RBracLoc; }
1364 static bool classof(const Stmt *T) {
1365 return T->getStmtClass() == ObjCMessageExprClass;
1369 child_range children();
1371 typedef ExprIterator arg_iterator;
1372 typedef ConstExprIterator const_arg_iterator;
1374 arg_iterator arg_begin() { return reinterpret_cast<Stmt **>(getArgs()); }
1375 arg_iterator arg_end() {
1376 return reinterpret_cast<Stmt **>(getArgs() + NumArgs);
1378 const_arg_iterator arg_begin() const {
1379 return reinterpret_cast<Stmt const * const*>(getArgs());
1381 const_arg_iterator arg_end() const {
1382 return reinterpret_cast<Stmt const * const*>(getArgs() + NumArgs);
1385 friend class ASTStmtReader;
1386 friend class ASTStmtWriter;
1389 /// ObjCIsaExpr - Represent X->isa and X.isa when X is an ObjC 'id' type.
1390 /// (similar in spirit to MemberExpr).
1391 class ObjCIsaExpr : public Expr {
1392 /// Base - the expression for the base object pointer.
1395 /// IsaMemberLoc - This is the location of the 'isa'.
1396 SourceLocation IsaMemberLoc;
1398 /// OpLoc - This is the location of '.' or '->'
1399 SourceLocation OpLoc;
1401 /// IsArrow - True if this is "X->F", false if this is "X.F".
1404 ObjCIsaExpr(Expr *base, bool isarrow, SourceLocation l, SourceLocation oploc,
1406 : Expr(ObjCIsaExprClass, ty, VK_LValue, OK_Ordinary,
1407 /*TypeDependent=*/false, base->isValueDependent(),
1408 base->isInstantiationDependent(),
1409 /*ContainsUnexpandedParameterPack=*/false),
1410 Base(base), IsaMemberLoc(l), OpLoc(oploc), IsArrow(isarrow) {}
1412 /// \brief Build an empty expression.
1413 explicit ObjCIsaExpr(EmptyShell Empty) : Expr(ObjCIsaExprClass, Empty) { }
1415 void setBase(Expr *E) { Base = E; }
1416 Expr *getBase() const { return cast<Expr>(Base); }
1418 bool isArrow() const { return IsArrow; }
1419 void setArrow(bool A) { IsArrow = A; }
1421 /// getMemberLoc - Return the location of the "member", in X->F, it is the
1422 /// location of 'F'.
1423 SourceLocation getIsaMemberLoc() const { return IsaMemberLoc; }
1424 void setIsaMemberLoc(SourceLocation L) { IsaMemberLoc = L; }
1426 SourceLocation getOpLoc() const { return OpLoc; }
1427 void setOpLoc(SourceLocation L) { OpLoc = L; }
1429 SourceLocation getLocStart() const LLVM_READONLY {
1430 return getBase()->getLocStart();
1433 SourceLocation getBaseLocEnd() const LLVM_READONLY {
1434 return getBase()->getLocEnd();
1437 SourceLocation getLocEnd() const LLVM_READONLY { return IsaMemberLoc; }
1439 SourceLocation getExprLoc() const LLVM_READONLY { return IsaMemberLoc; }
1441 static bool classof(const Stmt *T) {
1442 return T->getStmtClass() == ObjCIsaExprClass;
1446 child_range children() { return child_range(&Base, &Base+1); }
1450 /// ObjCIndirectCopyRestoreExpr - Represents the passing of a function
1451 /// argument by indirect copy-restore in ARC. This is used to support
1452 /// passing indirect arguments with the wrong lifetime, e.g. when
1453 /// passing the address of a __strong local variable to an 'out'
1454 /// parameter. This expression kind is only valid in an "argument"
1455 /// position to some sort of call expression.
1457 /// The parameter must have type 'pointer to T', and the argument must
1458 /// have type 'pointer to U', where T and U agree except possibly in
1459 /// qualification. If the argument value is null, then a null pointer
1460 /// is passed; otherwise it points to an object A, and:
1461 /// 1. A temporary object B of type T is initialized, either by
1462 /// zero-initialization (used when initializing an 'out' parameter)
1463 /// or copy-initialization (used when initializing an 'inout'
1465 /// 2. The address of the temporary is passed to the function.
1466 /// 3. If the call completes normally, A is move-assigned from B.
1467 /// 4. Finally, A is destroyed immediately.
1469 /// Currently 'T' must be a retainable object lifetime and must be
1470 /// __autoreleasing; this qualifier is ignored when initializing
1472 class ObjCIndirectCopyRestoreExpr : public Expr {
1475 // unsigned ObjCIndirectCopyRestoreBits.ShouldCopy : 1;
1477 friend class ASTReader;
1478 friend class ASTStmtReader;
1480 void setShouldCopy(bool shouldCopy) {
1481 ObjCIndirectCopyRestoreExprBits.ShouldCopy = shouldCopy;
1484 explicit ObjCIndirectCopyRestoreExpr(EmptyShell Empty)
1485 : Expr(ObjCIndirectCopyRestoreExprClass, Empty) { }
1488 ObjCIndirectCopyRestoreExpr(Expr *operand, QualType type, bool shouldCopy)
1489 : Expr(ObjCIndirectCopyRestoreExprClass, type, VK_LValue, OK_Ordinary,
1490 operand->isTypeDependent(), operand->isValueDependent(),
1491 operand->isInstantiationDependent(),
1492 operand->containsUnexpandedParameterPack()),
1494 setShouldCopy(shouldCopy);
1497 Expr *getSubExpr() { return cast<Expr>(Operand); }
1498 const Expr *getSubExpr() const { return cast<Expr>(Operand); }
1500 /// shouldCopy - True if we should do the 'copy' part of the
1501 /// copy-restore. If false, the temporary will be zero-initialized.
1502 bool shouldCopy() const { return ObjCIndirectCopyRestoreExprBits.ShouldCopy; }
1504 child_range children() { return child_range(&Operand, &Operand+1); }
1506 // Source locations are determined by the subexpression.
1507 SourceLocation getLocStart() const LLVM_READONLY {
1508 return Operand->getLocStart();
1510 SourceLocation getLocEnd() const LLVM_READONLY { return Operand->getLocEnd();}
1512 SourceLocation getExprLoc() const LLVM_READONLY {
1513 return getSubExpr()->getExprLoc();
1516 static bool classof(const Stmt *s) {
1517 return s->getStmtClass() == ObjCIndirectCopyRestoreExprClass;
1521 /// \brief An Objective-C "bridged" cast expression, which casts between
1522 /// Objective-C pointers and C pointers, transferring ownership in the process.
1525 /// NSString *str = (__bridge_transfer NSString *)CFCreateString();
1527 class ObjCBridgedCastExpr : public ExplicitCastExpr {
1528 SourceLocation LParenLoc;
1529 SourceLocation BridgeKeywordLoc;
1532 friend class ASTStmtReader;
1533 friend class ASTStmtWriter;
1536 ObjCBridgedCastExpr(SourceLocation LParenLoc, ObjCBridgeCastKind Kind,
1537 CastKind CK, SourceLocation BridgeKeywordLoc,
1538 TypeSourceInfo *TSInfo, Expr *Operand)
1539 : ExplicitCastExpr(ObjCBridgedCastExprClass, TSInfo->getType(), VK_RValue,
1540 CK, Operand, 0, TSInfo),
1541 LParenLoc(LParenLoc), BridgeKeywordLoc(BridgeKeywordLoc), Kind(Kind) { }
1543 /// \brief Construct an empty Objective-C bridged cast.
1544 explicit ObjCBridgedCastExpr(EmptyShell Shell)
1545 : ExplicitCastExpr(ObjCBridgedCastExprClass, Shell, 0) { }
1547 SourceLocation getLParenLoc() const { return LParenLoc; }
1549 /// \brief Determine which kind of bridge is being performed via this cast.
1550 ObjCBridgeCastKind getBridgeKind() const {
1551 return static_cast<ObjCBridgeCastKind>(Kind);
1554 /// \brief Retrieve the kind of bridge being performed as a string.
1555 StringRef getBridgeKindName() const;
1557 /// \brief The location of the bridge keyword.
1558 SourceLocation getBridgeKeywordLoc() const { return BridgeKeywordLoc; }
1560 SourceLocation getLocStart() const LLVM_READONLY { return LParenLoc; }
1561 SourceLocation getLocEnd() const LLVM_READONLY {
1562 return getSubExpr()->getLocEnd();
1565 static bool classof(const Stmt *T) {
1566 return T->getStmtClass() == ObjCBridgedCastExprClass;
1570 } // end namespace clang