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(ASTContext &C,
147 ArrayRef<Expr *> Elements,
148 QualType T, ObjCMethodDecl * Method,
151 static ObjCArrayLiteral *CreateEmpty(ASTContext &C, unsigned NumElements);
153 SourceLocation getLocStart() const LLVM_READONLY { return Range.getBegin(); }
154 SourceLocation getLocEnd() const LLVM_READONLY { return Range.getEnd(); }
155 SourceRange getSourceRange() const LLVM_READONLY { return Range; }
157 static bool classof(const Stmt *T) {
158 return T->getStmtClass() == ObjCArrayLiteralClass;
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 Optional<unsigned> NumExpansions;
211 /// \brief Determines whether this dictionary element is a pack expansion.
212 bool isPackExpansion() const { return EllipsisLoc.isValid(); }
214 } // end namespace clang
217 template <> struct isPodLike<clang::ObjCDictionaryElement> : llvm::true_type {};
221 /// ObjCDictionaryLiteral - AST node to represent objective-c dictionary
222 /// literals; as in: @{@"name" : NSUserName(), @"date" : [NSDate date] };
223 class ObjCDictionaryLiteral : public Expr {
224 /// \brief Key/value pair used to store the key and value of a given element.
226 /// Objects of this type are stored directly after the expression.
227 struct KeyValuePair {
232 /// \brief Data that describes an element that is a pack expansion, used if any
233 /// of the elements in the dictionary literal are pack expansions.
234 struct ExpansionData {
235 /// \brief The location of the ellipsis, if this element is a pack
237 SourceLocation EllipsisLoc;
239 /// \brief If non-zero, the number of elements that this pack
240 /// expansion will expand to (+1).
241 unsigned NumExpansionsPlusOne;
244 /// \brief The number of elements in this dictionary literal.
245 unsigned NumElements : 31;
247 /// \brief Determine whether this dictionary literal has any pack expansions.
249 /// If the dictionary literal has pack expansions, then there will
250 /// be an array of pack expansion data following the array of
251 /// key/value pairs, which provide the locations of the ellipses (if
252 /// any) and number of elements in the expansion (if known). If
253 /// there are no pack expansions, we optimize away this storage.
254 unsigned HasPackExpansions : 1;
257 ObjCMethodDecl *DictWithObjectsMethod;
259 ObjCDictionaryLiteral(ArrayRef<ObjCDictionaryElement> VK,
260 bool HasPackExpansions,
261 QualType T, ObjCMethodDecl *method,
264 explicit ObjCDictionaryLiteral(EmptyShell Empty, unsigned NumElements,
265 bool HasPackExpansions)
266 : Expr(ObjCDictionaryLiteralClass, Empty), NumElements(NumElements),
267 HasPackExpansions(HasPackExpansions) {}
269 KeyValuePair *getKeyValues() {
270 return reinterpret_cast<KeyValuePair *>(this + 1);
273 const KeyValuePair *getKeyValues() const {
274 return reinterpret_cast<const KeyValuePair *>(this + 1);
277 ExpansionData *getExpansionData() {
278 if (!HasPackExpansions)
281 return reinterpret_cast<ExpansionData *>(getKeyValues() + NumElements);
284 const ExpansionData *getExpansionData() const {
285 if (!HasPackExpansions)
288 return reinterpret_cast<const ExpansionData *>(getKeyValues()+NumElements);
292 static ObjCDictionaryLiteral *Create(ASTContext &C,
293 ArrayRef<ObjCDictionaryElement> VK,
294 bool HasPackExpansions,
295 QualType T, ObjCMethodDecl *method,
298 static ObjCDictionaryLiteral *CreateEmpty(ASTContext &C,
299 unsigned NumElements,
300 bool HasPackExpansions);
302 /// getNumElements - Return number of elements of objective-c dictionary
304 unsigned getNumElements() const { return NumElements; }
306 ObjCDictionaryElement getKeyValueElement(unsigned Index) const {
307 assert((Index < NumElements) && "Arg access out of range!");
308 const KeyValuePair &KV = getKeyValues()[Index];
309 ObjCDictionaryElement Result = { KV.Key, KV.Value, SourceLocation(), None };
310 if (HasPackExpansions) {
311 const ExpansionData &Expansion = getExpansionData()[Index];
312 Result.EllipsisLoc = Expansion.EllipsisLoc;
313 if (Expansion.NumExpansionsPlusOne > 0)
314 Result.NumExpansions = Expansion.NumExpansionsPlusOne - 1;
319 ObjCMethodDecl *getDictWithObjectsMethod() const
320 { return DictWithObjectsMethod; }
322 SourceLocation getLocStart() const LLVM_READONLY { return Range.getBegin(); }
323 SourceLocation getLocEnd() const LLVM_READONLY { return Range.getEnd(); }
324 SourceRange getSourceRange() const LLVM_READONLY { return Range; }
326 static bool classof(const Stmt *T) {
327 return T->getStmtClass() == ObjCDictionaryLiteralClass;
331 child_range children() {
332 // Note: we're taking advantage of the layout of the KeyValuePair struct
333 // here. If that struct changes, this code will need to change as well.
334 return child_range(reinterpret_cast<Stmt **>(this + 1),
335 reinterpret_cast<Stmt **>(this + 1) + NumElements * 2);
338 friend class ASTStmtReader;
339 friend class ASTStmtWriter;
343 /// ObjCEncodeExpr, used for \@encode in Objective-C. \@encode has the same
344 /// type and behavior as StringLiteral except that the string initializer is
345 /// obtained from ASTContext with the encoding type as an argument.
346 class ObjCEncodeExpr : public Expr {
347 TypeSourceInfo *EncodedType;
348 SourceLocation AtLoc, RParenLoc;
350 ObjCEncodeExpr(QualType T, TypeSourceInfo *EncodedType,
351 SourceLocation at, SourceLocation rp)
352 : Expr(ObjCEncodeExprClass, T, VK_LValue, OK_Ordinary,
353 EncodedType->getType()->isDependentType(),
354 EncodedType->getType()->isDependentType(),
355 EncodedType->getType()->isInstantiationDependentType(),
356 EncodedType->getType()->containsUnexpandedParameterPack()),
357 EncodedType(EncodedType), AtLoc(at), RParenLoc(rp) {}
359 explicit ObjCEncodeExpr(EmptyShell Empty) : Expr(ObjCEncodeExprClass, Empty){}
362 SourceLocation getAtLoc() const { return AtLoc; }
363 void setAtLoc(SourceLocation L) { AtLoc = L; }
364 SourceLocation getRParenLoc() const { return RParenLoc; }
365 void setRParenLoc(SourceLocation L) { RParenLoc = L; }
367 QualType getEncodedType() const { return EncodedType->getType(); }
369 TypeSourceInfo *getEncodedTypeSourceInfo() const { return EncodedType; }
370 void setEncodedTypeSourceInfo(TypeSourceInfo *EncType) {
371 EncodedType = EncType;
374 SourceLocation getLocStart() const LLVM_READONLY { return AtLoc; }
375 SourceLocation getLocEnd() const LLVM_READONLY { return RParenLoc; }
377 static bool classof(const Stmt *T) {
378 return T->getStmtClass() == ObjCEncodeExprClass;
382 child_range children() { return child_range(); }
385 /// ObjCSelectorExpr used for \@selector in Objective-C.
386 class ObjCSelectorExpr : public Expr {
388 SourceLocation AtLoc, RParenLoc;
390 ObjCSelectorExpr(QualType T, Selector selInfo,
391 SourceLocation at, SourceLocation rp)
392 : Expr(ObjCSelectorExprClass, T, VK_RValue, OK_Ordinary, false, false,
394 SelName(selInfo), AtLoc(at), RParenLoc(rp){}
395 explicit ObjCSelectorExpr(EmptyShell Empty)
396 : Expr(ObjCSelectorExprClass, Empty) {}
398 Selector getSelector() const { return SelName; }
399 void setSelector(Selector S) { SelName = S; }
401 SourceLocation getAtLoc() const { return AtLoc; }
402 SourceLocation getRParenLoc() const { return RParenLoc; }
403 void setAtLoc(SourceLocation L) { AtLoc = L; }
404 void setRParenLoc(SourceLocation L) { RParenLoc = L; }
406 SourceLocation getLocStart() const LLVM_READONLY { return AtLoc; }
407 SourceLocation getLocEnd() const LLVM_READONLY { return RParenLoc; }
409 /// getNumArgs - Return the number of actual arguments to this call.
410 unsigned getNumArgs() const { return SelName.getNumArgs(); }
412 static bool classof(const Stmt *T) {
413 return T->getStmtClass() == ObjCSelectorExprClass;
417 child_range children() { return child_range(); }
420 /// ObjCProtocolExpr used for protocol expression in Objective-C.
422 /// This is used as: \@protocol(foo), as in:
424 /// [obj conformsToProtocol:@protocol(foo)]
427 /// The return type is "Protocol*".
428 class ObjCProtocolExpr : public Expr {
429 ObjCProtocolDecl *TheProtocol;
430 SourceLocation AtLoc, ProtoLoc, RParenLoc;
432 ObjCProtocolExpr(QualType T, ObjCProtocolDecl *protocol,
433 SourceLocation at, SourceLocation protoLoc, SourceLocation rp)
434 : Expr(ObjCProtocolExprClass, T, VK_RValue, OK_Ordinary, false, false,
436 TheProtocol(protocol), AtLoc(at), ProtoLoc(protoLoc), RParenLoc(rp) {}
437 explicit ObjCProtocolExpr(EmptyShell Empty)
438 : Expr(ObjCProtocolExprClass, Empty) {}
440 ObjCProtocolDecl *getProtocol() const { return TheProtocol; }
441 void setProtocol(ObjCProtocolDecl *P) { TheProtocol = P; }
443 SourceLocation getProtocolIdLoc() const { return ProtoLoc; }
444 SourceLocation getAtLoc() const { return AtLoc; }
445 SourceLocation getRParenLoc() const { return RParenLoc; }
446 void setAtLoc(SourceLocation L) { AtLoc = L; }
447 void setRParenLoc(SourceLocation L) { RParenLoc = L; }
449 SourceLocation getLocStart() const LLVM_READONLY { return AtLoc; }
450 SourceLocation getLocEnd() const LLVM_READONLY { return RParenLoc; }
452 static bool classof(const Stmt *T) {
453 return T->getStmtClass() == ObjCProtocolExprClass;
457 child_range children() { return child_range(); }
459 friend class ASTStmtReader;
460 friend class ASTStmtWriter;
463 /// ObjCIvarRefExpr - A reference to an ObjC instance variable.
464 class ObjCIvarRefExpr : public Expr {
468 /// OpLoc - This is the location of '.' or '->'
469 SourceLocation OpLoc;
471 bool IsArrow:1; // True if this is "X->F", false if this is "X.F".
472 bool IsFreeIvar:1; // True if ivar reference has no base (self assumed).
475 ObjCIvarRefExpr(ObjCIvarDecl *d, QualType t,
476 SourceLocation l, SourceLocation oploc,
478 bool arrow = false, bool freeIvar = false) :
479 Expr(ObjCIvarRefExprClass, t, VK_LValue,
480 d->isBitField() ? OK_BitField : OK_Ordinary,
481 /*TypeDependent=*/false, base->isValueDependent(),
482 base->isInstantiationDependent(),
483 base->containsUnexpandedParameterPack()),
484 D(d), Base(base), Loc(l), OpLoc(oploc),
485 IsArrow(arrow), IsFreeIvar(freeIvar) {}
487 explicit ObjCIvarRefExpr(EmptyShell Empty)
488 : Expr(ObjCIvarRefExprClass, Empty) {}
490 ObjCIvarDecl *getDecl() { return D; }
491 const ObjCIvarDecl *getDecl() const { return D; }
492 void setDecl(ObjCIvarDecl *d) { D = d; }
494 const Expr *getBase() const { return cast<Expr>(Base); }
495 Expr *getBase() { return cast<Expr>(Base); }
496 void setBase(Expr * base) { Base = base; }
498 bool isArrow() const { return IsArrow; }
499 bool isFreeIvar() const { return IsFreeIvar; }
500 void setIsArrow(bool A) { IsArrow = A; }
501 void setIsFreeIvar(bool A) { IsFreeIvar = A; }
503 SourceLocation getLocation() const { return Loc; }
504 void setLocation(SourceLocation L) { Loc = L; }
506 SourceLocation getLocStart() const LLVM_READONLY {
507 return isFreeIvar() ? Loc : getBase()->getLocStart();
509 SourceLocation getLocEnd() const LLVM_READONLY { return Loc; }
511 SourceLocation getOpLoc() const { return OpLoc; }
512 void setOpLoc(SourceLocation L) { OpLoc = L; }
514 static bool classof(const Stmt *T) {
515 return T->getStmtClass() == ObjCIvarRefExprClass;
519 child_range children() { return child_range(&Base, &Base+1); }
522 /// ObjCPropertyRefExpr - A dot-syntax expression to access an ObjC
524 class ObjCPropertyRefExpr : public Expr {
526 /// If the bool is true, this is an implicit property reference; the
527 /// pointer is an (optional) ObjCMethodDecl and Setter may be set.
528 /// if the bool is false, this is an explicit property reference;
529 /// the pointer is an ObjCPropertyDecl and Setter is always null.
530 llvm::PointerIntPair<NamedDecl*, 1, bool> PropertyOrGetter;
532 /// \brief Indicates whether the property reference will result in a message
533 /// to the getter, the setter, or both.
534 /// This applies to both implicit and explicit property references.
535 enum MethodRefFlags {
537 MethodRef_Getter = 0x1,
538 MethodRef_Setter = 0x2
541 /// \brief Contains the Setter method pointer and MethodRefFlags bit flags.
542 llvm::PointerIntPair<ObjCMethodDecl *, 2, unsigned> SetterAndMethodRefFlags;
544 // FIXME: Maybe we should store the property identifier here,
545 // because it's not rederivable from the other data when there's an
546 // implicit property with no getter (because the 'foo' -> 'setFoo:'
547 // transformation is lossy on the first character).
549 SourceLocation IdLoc;
551 /// \brief When the receiver in property access is 'super', this is
552 /// the location of the 'super' keyword. When it's an interface,
553 /// this is that interface.
554 SourceLocation ReceiverLoc;
555 llvm::PointerUnion3<Stmt*, const Type*, ObjCInterfaceDecl*> Receiver;
558 ObjCPropertyRefExpr(ObjCPropertyDecl *PD, QualType t,
559 ExprValueKind VK, ExprObjectKind OK,
560 SourceLocation l, Expr *base)
561 : Expr(ObjCPropertyRefExprClass, t, VK, OK,
562 /*TypeDependent=*/false, base->isValueDependent(),
563 base->isInstantiationDependent(),
564 base->containsUnexpandedParameterPack()),
565 PropertyOrGetter(PD, false), SetterAndMethodRefFlags(),
566 IdLoc(l), ReceiverLoc(), Receiver(base) {
567 assert(t->isSpecificPlaceholderType(BuiltinType::PseudoObject));
570 ObjCPropertyRefExpr(ObjCPropertyDecl *PD, QualType t,
571 ExprValueKind VK, ExprObjectKind OK,
572 SourceLocation l, SourceLocation sl, QualType st)
573 : Expr(ObjCPropertyRefExprClass, t, VK, OK,
574 /*TypeDependent=*/false, false, st->isInstantiationDependentType(),
575 st->containsUnexpandedParameterPack()),
576 PropertyOrGetter(PD, false), SetterAndMethodRefFlags(),
577 IdLoc(l), ReceiverLoc(sl), Receiver(st.getTypePtr()) {
578 assert(t->isSpecificPlaceholderType(BuiltinType::PseudoObject));
581 ObjCPropertyRefExpr(ObjCMethodDecl *Getter, ObjCMethodDecl *Setter,
582 QualType T, ExprValueKind VK, ExprObjectKind OK,
583 SourceLocation IdLoc, Expr *Base)
584 : Expr(ObjCPropertyRefExprClass, T, VK, OK, false,
585 Base->isValueDependent(), Base->isInstantiationDependent(),
586 Base->containsUnexpandedParameterPack()),
587 PropertyOrGetter(Getter, true), SetterAndMethodRefFlags(Setter, 0),
588 IdLoc(IdLoc), ReceiverLoc(), Receiver(Base) {
589 assert(T->isSpecificPlaceholderType(BuiltinType::PseudoObject));
592 ObjCPropertyRefExpr(ObjCMethodDecl *Getter, ObjCMethodDecl *Setter,
593 QualType T, ExprValueKind VK, ExprObjectKind OK,
594 SourceLocation IdLoc,
595 SourceLocation SuperLoc, QualType SuperTy)
596 : Expr(ObjCPropertyRefExprClass, T, VK, OK, false, false, false, false),
597 PropertyOrGetter(Getter, true), SetterAndMethodRefFlags(Setter, 0),
598 IdLoc(IdLoc), ReceiverLoc(SuperLoc), Receiver(SuperTy.getTypePtr()) {
599 assert(T->isSpecificPlaceholderType(BuiltinType::PseudoObject));
602 ObjCPropertyRefExpr(ObjCMethodDecl *Getter, ObjCMethodDecl *Setter,
603 QualType T, ExprValueKind VK, ExprObjectKind OK,
604 SourceLocation IdLoc,
605 SourceLocation ReceiverLoc, ObjCInterfaceDecl *Receiver)
606 : Expr(ObjCPropertyRefExprClass, T, VK, OK, false, false, false, false),
607 PropertyOrGetter(Getter, true), SetterAndMethodRefFlags(Setter, 0),
608 IdLoc(IdLoc), ReceiverLoc(ReceiverLoc), Receiver(Receiver) {
609 assert(T->isSpecificPlaceholderType(BuiltinType::PseudoObject));
612 explicit ObjCPropertyRefExpr(EmptyShell Empty)
613 : Expr(ObjCPropertyRefExprClass, Empty) {}
615 bool isImplicitProperty() const { return PropertyOrGetter.getInt(); }
616 bool isExplicitProperty() const { return !PropertyOrGetter.getInt(); }
618 ObjCPropertyDecl *getExplicitProperty() const {
619 assert(!isImplicitProperty());
620 return cast<ObjCPropertyDecl>(PropertyOrGetter.getPointer());
623 ObjCMethodDecl *getImplicitPropertyGetter() const {
624 assert(isImplicitProperty());
625 return cast_or_null<ObjCMethodDecl>(PropertyOrGetter.getPointer());
628 ObjCMethodDecl *getImplicitPropertySetter() const {
629 assert(isImplicitProperty());
630 return SetterAndMethodRefFlags.getPointer();
633 Selector getGetterSelector() const {
634 if (isImplicitProperty())
635 return getImplicitPropertyGetter()->getSelector();
636 return getExplicitProperty()->getGetterName();
639 Selector getSetterSelector() const {
640 if (isImplicitProperty())
641 return getImplicitPropertySetter()->getSelector();
642 return getExplicitProperty()->getSetterName();
645 /// \brief True if the property reference will result in a message to the
647 /// This applies to both implicit and explicit property references.
648 bool isMessagingGetter() const {
649 return SetterAndMethodRefFlags.getInt() & MethodRef_Getter;
652 /// \brief True if the property reference will result in a message to the
654 /// This applies to both implicit and explicit property references.
655 bool isMessagingSetter() const {
656 return SetterAndMethodRefFlags.getInt() & MethodRef_Setter;
659 void setIsMessagingGetter(bool val = true) {
660 setMethodRefFlag(MethodRef_Getter, val);
663 void setIsMessagingSetter(bool val = true) {
664 setMethodRefFlag(MethodRef_Setter, val);
667 const Expr *getBase() const {
668 return cast<Expr>(Receiver.get<Stmt*>());
671 return cast<Expr>(Receiver.get<Stmt*>());
674 SourceLocation getLocation() const { return IdLoc; }
676 SourceLocation getReceiverLocation() const { return ReceiverLoc; }
677 QualType getSuperReceiverType() const {
678 return QualType(Receiver.get<const Type*>(), 0);
680 QualType getGetterResultType() const {
682 if (isExplicitProperty()) {
683 const ObjCPropertyDecl *PDecl = getExplicitProperty();
684 if (const ObjCMethodDecl *Getter = PDecl->getGetterMethodDecl())
685 ResultType = Getter->getResultType();
687 ResultType = PDecl->getType();
689 const ObjCMethodDecl *Getter = getImplicitPropertyGetter();
691 ResultType = Getter->getResultType(); // with reference!
696 QualType getSetterArgType() const {
698 if (isImplicitProperty()) {
699 const ObjCMethodDecl *Setter = getImplicitPropertySetter();
700 ObjCMethodDecl::param_const_iterator P = Setter->param_begin();
701 ArgType = (*P)->getType();
703 if (ObjCPropertyDecl *PDecl = getExplicitProperty())
704 if (const ObjCMethodDecl *Setter = PDecl->getSetterMethodDecl()) {
705 ObjCMethodDecl::param_const_iterator P = Setter->param_begin();
706 ArgType = (*P)->getType();
708 if (ArgType.isNull())
714 ObjCInterfaceDecl *getClassReceiver() const {
715 return Receiver.get<ObjCInterfaceDecl*>();
717 bool isObjectReceiver() const { return Receiver.is<Stmt*>(); }
718 bool isSuperReceiver() const { return Receiver.is<const Type*>(); }
719 bool isClassReceiver() const { return Receiver.is<ObjCInterfaceDecl*>(); }
721 SourceLocation getLocStart() const LLVM_READONLY {
722 return isObjectReceiver() ? getBase()->getLocStart() :getReceiverLocation();
724 SourceLocation getLocEnd() const LLVM_READONLY { return IdLoc; }
726 static bool classof(const Stmt *T) {
727 return T->getStmtClass() == ObjCPropertyRefExprClass;
731 child_range children() {
732 if (Receiver.is<Stmt*>()) {
733 Stmt **begin = reinterpret_cast<Stmt**>(&Receiver); // hack!
734 return child_range(begin, begin+1);
736 return child_range();
740 friend class ASTStmtReader;
741 friend class ASTStmtWriter;
742 void setExplicitProperty(ObjCPropertyDecl *D, unsigned methRefFlags) {
743 PropertyOrGetter.setPointer(D);
744 PropertyOrGetter.setInt(false);
745 SetterAndMethodRefFlags.setPointer(0);
746 SetterAndMethodRefFlags.setInt(methRefFlags);
748 void setImplicitProperty(ObjCMethodDecl *Getter, ObjCMethodDecl *Setter,
749 unsigned methRefFlags) {
750 PropertyOrGetter.setPointer(Getter);
751 PropertyOrGetter.setInt(true);
752 SetterAndMethodRefFlags.setPointer(Setter);
753 SetterAndMethodRefFlags.setInt(methRefFlags);
755 void setBase(Expr *Base) { Receiver = Base; }
756 void setSuperReceiver(QualType T) { Receiver = T.getTypePtr(); }
757 void setClassReceiver(ObjCInterfaceDecl *D) { Receiver = D; }
759 void setLocation(SourceLocation L) { IdLoc = L; }
760 void setReceiverLocation(SourceLocation Loc) { ReceiverLoc = Loc; }
762 void setMethodRefFlag(MethodRefFlags flag, bool val) {
763 unsigned f = SetterAndMethodRefFlags.getInt();
768 SetterAndMethodRefFlags.setInt(f);
772 /// ObjCSubscriptRefExpr - used for array and dictionary subscripting.
773 /// array[4] = array[3]; dictionary[key] = dictionary[alt_key];
775 class ObjCSubscriptRefExpr : public Expr {
776 // Location of ']' in an indexing expression.
777 SourceLocation RBracket;
778 // array/dictionary base expression.
779 // for arrays, this is a numeric expression. For dictionaries, this is
780 // an objective-c object pointer expression.
781 enum { BASE, KEY, END_EXPR };
782 Stmt* SubExprs[END_EXPR];
784 ObjCMethodDecl *GetAtIndexMethodDecl;
786 // For immutable objects this is null. When ObjCSubscriptRefExpr is to read
787 // an indexed object this is null too.
788 ObjCMethodDecl *SetAtIndexMethodDecl;
792 ObjCSubscriptRefExpr(Expr *base, Expr *key, QualType T,
793 ExprValueKind VK, ExprObjectKind OK,
794 ObjCMethodDecl *getMethod,
795 ObjCMethodDecl *setMethod, SourceLocation RB)
796 : Expr(ObjCSubscriptRefExprClass, T, VK, OK,
797 base->isTypeDependent() || key->isTypeDependent(),
798 base->isValueDependent() || key->isValueDependent(),
799 base->isInstantiationDependent() || key->isInstantiationDependent(),
800 (base->containsUnexpandedParameterPack() ||
801 key->containsUnexpandedParameterPack())),
803 GetAtIndexMethodDecl(getMethod),
804 SetAtIndexMethodDecl(setMethod)
805 {SubExprs[BASE] = base; SubExprs[KEY] = key;}
807 explicit ObjCSubscriptRefExpr(EmptyShell Empty)
808 : Expr(ObjCSubscriptRefExprClass, Empty) {}
810 static ObjCSubscriptRefExpr *Create(ASTContext &C,
812 Expr *key, QualType T,
813 ObjCMethodDecl *getMethod,
814 ObjCMethodDecl *setMethod,
817 SourceLocation getRBracket() const { return RBracket; }
818 void setRBracket(SourceLocation RB) { RBracket = RB; }
820 SourceLocation getLocStart() const LLVM_READONLY {
821 return SubExprs[BASE]->getLocStart();
823 SourceLocation getLocEnd() const LLVM_READONLY { return RBracket; }
825 static bool classof(const Stmt *T) {
826 return T->getStmtClass() == ObjCSubscriptRefExprClass;
829 Expr *getBaseExpr() const { return cast<Expr>(SubExprs[BASE]); }
830 void setBaseExpr(Stmt *S) { SubExprs[BASE] = S; }
832 Expr *getKeyExpr() const { return cast<Expr>(SubExprs[KEY]); }
833 void setKeyExpr(Stmt *S) { SubExprs[KEY] = S; }
835 ObjCMethodDecl *getAtIndexMethodDecl() const {
836 return GetAtIndexMethodDecl;
839 ObjCMethodDecl *setAtIndexMethodDecl() const {
840 return SetAtIndexMethodDecl;
843 bool isArraySubscriptRefExpr() const {
844 return getKeyExpr()->getType()->isIntegralOrEnumerationType();
847 child_range children() {
848 return child_range(SubExprs, SubExprs+END_EXPR);
851 friend class ASTStmtReader;
855 /// \brief An expression that sends a message to the given Objective-C
858 /// The following contains two message send expressions:
861 /// [[NSString alloc] initWithString:@"Hello"]
864 /// The innermost message send invokes the "alloc" class method on the
865 /// NSString class, while the outermost message send invokes the
866 /// "initWithString" instance method on the object returned from
867 /// NSString's "alloc". In all, an Objective-C message send can take
868 /// on four different (although related) forms:
870 /// 1. Send to an object instance.
871 /// 2. Send to a class.
872 /// 3. Send to the superclass instance of the current class.
873 /// 4. Send to the superclass of the current class.
875 /// All four kinds of message sends are modeled by the ObjCMessageExpr
876 /// class, and can be distinguished via \c getReceiverKind(). Example:
878 class ObjCMessageExpr : public Expr {
879 /// \brief Stores either the selector that this message is sending
880 /// to (when \c HasMethod is zero) or an \c ObjCMethodDecl pointer
881 /// referring to the method that we type-checked against.
882 uintptr_t SelectorOrMethod;
884 enum { NumArgsBitWidth = 16 };
886 /// \brief The number of arguments in the message send, not
887 /// including the receiver.
888 unsigned NumArgs : NumArgsBitWidth;
890 void setNumArgs(unsigned Num) {
891 assert((Num >> NumArgsBitWidth) == 0 && "Num of args is out of range!");
895 /// \brief The kind of message send this is, which is one of the
896 /// ReceiverKind values.
898 /// We pad this out to a byte to avoid excessive masking and shifting.
901 /// \brief Whether we have an actual method prototype in \c
902 /// SelectorOrMethod.
904 /// When non-zero, we have a method declaration; otherwise, we just
906 unsigned HasMethod : 1;
908 /// \brief Whether this message send is a "delegate init call",
909 /// i.e. a call of an init method on self from within an init method.
910 unsigned IsDelegateInitCall : 1;
912 /// \brief Whether this message send was implicitly generated by
913 /// the implementation rather than explicitly written by the user.
914 unsigned IsImplicit : 1;
916 /// \brief Whether the locations of the selector identifiers are in a
917 /// "standard" position, a enum SelectorLocationsKind.
918 unsigned SelLocsKind : 2;
920 /// \brief When the message expression is a send to 'super', this is
921 /// the location of the 'super' keyword.
922 SourceLocation SuperLoc;
924 /// \brief The source locations of the open and close square
925 /// brackets ('[' and ']', respectively).
926 SourceLocation LBracLoc, RBracLoc;
928 ObjCMessageExpr(EmptyShell Empty, unsigned NumArgs)
929 : Expr(ObjCMessageExprClass, Empty), SelectorOrMethod(0), Kind(0),
930 HasMethod(0), IsDelegateInitCall(0), IsImplicit(0), SelLocsKind(0) {
934 ObjCMessageExpr(QualType T, ExprValueKind VK,
935 SourceLocation LBracLoc,
936 SourceLocation SuperLoc,
937 bool IsInstanceSuper,
940 ArrayRef<SourceLocation> SelLocs,
941 SelectorLocationsKind SelLocsK,
942 ObjCMethodDecl *Method,
943 ArrayRef<Expr *> Args,
944 SourceLocation RBracLoc,
946 ObjCMessageExpr(QualType T, ExprValueKind VK,
947 SourceLocation LBracLoc,
948 TypeSourceInfo *Receiver,
950 ArrayRef<SourceLocation> SelLocs,
951 SelectorLocationsKind SelLocsK,
952 ObjCMethodDecl *Method,
953 ArrayRef<Expr *> Args,
954 SourceLocation RBracLoc,
956 ObjCMessageExpr(QualType T, ExprValueKind VK,
957 SourceLocation LBracLoc,
960 ArrayRef<SourceLocation> SelLocs,
961 SelectorLocationsKind SelLocsK,
962 ObjCMethodDecl *Method,
963 ArrayRef<Expr *> Args,
964 SourceLocation RBracLoc,
967 void initArgsAndSelLocs(ArrayRef<Expr *> Args,
968 ArrayRef<SourceLocation> SelLocs,
969 SelectorLocationsKind SelLocsK);
971 /// \brief Retrieve the pointer value of the message receiver.
972 void *getReceiverPointer() const {
973 return *const_cast<void **>(
974 reinterpret_cast<const void * const*>(this + 1));
977 /// \brief Set the pointer value of the message receiver.
978 void setReceiverPointer(void *Value) {
979 *reinterpret_cast<void **>(this + 1) = Value;
982 SelectorLocationsKind getSelLocsKind() const {
983 return (SelectorLocationsKind)SelLocsKind;
985 bool hasStandardSelLocs() const {
986 return getSelLocsKind() != SelLoc_NonStandard;
989 /// \brief Get a pointer to the stored selector identifiers locations array.
990 /// No locations will be stored if HasStandardSelLocs is true.
991 SourceLocation *getStoredSelLocs() {
992 return reinterpret_cast<SourceLocation*>(getArgs() + getNumArgs());
994 const SourceLocation *getStoredSelLocs() const {
995 return reinterpret_cast<const SourceLocation*>(getArgs() + getNumArgs());
998 /// \brief Get the number of stored selector identifiers locations.
999 /// No locations will be stored if HasStandardSelLocs is true.
1000 unsigned getNumStoredSelLocs() const {
1001 if (hasStandardSelLocs())
1003 return getNumSelectorLocs();
1006 static ObjCMessageExpr *alloc(ASTContext &C,
1007 ArrayRef<Expr *> Args,
1008 SourceLocation RBraceLoc,
1009 ArrayRef<SourceLocation> SelLocs,
1011 SelectorLocationsKind &SelLocsK);
1012 static ObjCMessageExpr *alloc(ASTContext &C,
1014 unsigned NumStoredSelLocs);
1017 /// \brief The kind of receiver this message is sending to.
1019 /// \brief The receiver is a class.
1021 /// \brief The receiver is an object instance.
1023 /// \brief The receiver is a superclass.
1025 /// \brief The receiver is the instance of the superclass object.
1029 /// \brief Create a message send to super.
1031 /// \param Context The ASTContext in which this expression will be created.
1033 /// \param T The result type of this message.
1035 /// \param VK The value kind of this message. A message returning
1036 /// a l-value or r-value reference will be an l-value or x-value,
1039 /// \param LBracLoc The location of the open square bracket '['.
1041 /// \param SuperLoc The location of the "super" keyword.
1043 /// \param IsInstanceSuper Whether this is an instance "super"
1044 /// message (otherwise, it's a class "super" message).
1046 /// \param Sel The selector used to determine which method gets called.
1048 /// \param Method The Objective-C method against which this message
1049 /// send was type-checked. May be NULL.
1051 /// \param Args The message send arguments.
1053 /// \param RBracLoc The location of the closing square bracket ']'.
1054 static ObjCMessageExpr *Create(ASTContext &Context, QualType T,
1056 SourceLocation LBracLoc,
1057 SourceLocation SuperLoc,
1058 bool IsInstanceSuper,
1061 ArrayRef<SourceLocation> SelLocs,
1062 ObjCMethodDecl *Method,
1063 ArrayRef<Expr *> Args,
1064 SourceLocation RBracLoc,
1067 /// \brief Create a class message send.
1069 /// \param Context The ASTContext in which this expression will be created.
1071 /// \param T The result type of this message.
1073 /// \param VK The value kind of this message. A message returning
1074 /// a l-value or r-value reference will be an l-value or x-value,
1077 /// \param LBracLoc The location of the open square bracket '['.
1079 /// \param Receiver The type of the receiver, including
1080 /// source-location information.
1082 /// \param Sel The selector used to determine which method gets called.
1084 /// \param Method The Objective-C method against which this message
1085 /// send was type-checked. May be NULL.
1087 /// \param Args The message send arguments.
1089 /// \param RBracLoc The location of the closing square bracket ']'.
1090 static ObjCMessageExpr *Create(ASTContext &Context, QualType T,
1092 SourceLocation LBracLoc,
1093 TypeSourceInfo *Receiver,
1095 ArrayRef<SourceLocation> SelLocs,
1096 ObjCMethodDecl *Method,
1097 ArrayRef<Expr *> Args,
1098 SourceLocation RBracLoc,
1101 /// \brief Create an instance message send.
1103 /// \param Context The ASTContext in which this expression will be created.
1105 /// \param T The result type of this message.
1107 /// \param VK The value kind of this message. A message returning
1108 /// a l-value or r-value reference will be an l-value or x-value,
1111 /// \param LBracLoc The location of the open square bracket '['.
1113 /// \param Receiver The expression used to produce the object that
1114 /// will receive this message.
1116 /// \param Sel The selector used to determine which method gets called.
1118 /// \param Method The Objective-C method against which this message
1119 /// send was type-checked. May be NULL.
1121 /// \param Args The message send arguments.
1123 /// \param RBracLoc The location of the closing square bracket ']'.
1124 static ObjCMessageExpr *Create(ASTContext &Context, QualType T,
1126 SourceLocation LBracLoc,
1129 ArrayRef<SourceLocation> SeLocs,
1130 ObjCMethodDecl *Method,
1131 ArrayRef<Expr *> Args,
1132 SourceLocation RBracLoc,
1135 /// \brief Create an empty Objective-C message expression, to be
1136 /// filled in by subsequent calls.
1138 /// \param Context The context in which the message send will be created.
1140 /// \param NumArgs The number of message arguments, not including
1142 static ObjCMessageExpr *CreateEmpty(ASTContext &Context,
1144 unsigned NumStoredSelLocs);
1146 /// \brief Indicates whether the message send was implicitly
1147 /// generated by the implementation. If false, it was written explicitly
1148 /// in the source code.
1149 bool isImplicit() const { return IsImplicit; }
1151 /// \brief Determine the kind of receiver that this message is being
1153 ReceiverKind getReceiverKind() const { return (ReceiverKind)Kind; }
1155 /// \brief Source range of the receiver.
1156 SourceRange getReceiverRange() const;
1158 /// \brief Determine whether this is an instance message to either a
1159 /// computed object or to super.
1160 bool isInstanceMessage() const {
1161 return getReceiverKind() == Instance || getReceiverKind() == SuperInstance;
1164 /// \brief Determine whether this is an class message to either a
1165 /// specified class or to super.
1166 bool isClassMessage() const {
1167 return getReceiverKind() == Class || getReceiverKind() == SuperClass;
1170 /// \brief Returns the object expression (receiver) for an instance message,
1171 /// or null for a message that is not an instance message.
1172 Expr *getInstanceReceiver() {
1173 if (getReceiverKind() == Instance)
1174 return static_cast<Expr *>(getReceiverPointer());
1178 const Expr *getInstanceReceiver() const {
1179 return const_cast<ObjCMessageExpr*>(this)->getInstanceReceiver();
1182 /// \brief Turn this message send into an instance message that
1183 /// computes the receiver object with the given expression.
1184 void setInstanceReceiver(Expr *rec) {
1186 setReceiverPointer(rec);
1189 /// \brief Returns the type of a class message send, or NULL if the
1190 /// message is not a class message.
1191 QualType getClassReceiver() const {
1192 if (TypeSourceInfo *TSInfo = getClassReceiverTypeInfo())
1193 return TSInfo->getType();
1198 /// \brief Returns a type-source information of a class message
1199 /// send, or NULL if the message is not a class message.
1200 TypeSourceInfo *getClassReceiverTypeInfo() const {
1201 if (getReceiverKind() == Class)
1202 return reinterpret_cast<TypeSourceInfo *>(getReceiverPointer());
1206 void setClassReceiver(TypeSourceInfo *TSInfo) {
1208 setReceiverPointer(TSInfo);
1211 /// \brief Retrieve the location of the 'super' keyword for a class
1212 /// or instance message to 'super', otherwise an invalid source location.
1213 SourceLocation getSuperLoc() const {
1214 if (getReceiverKind() == SuperInstance || getReceiverKind() == SuperClass)
1217 return SourceLocation();
1220 /// \brief Retrieve the receiver type to which this message is being directed.
1222 /// This routine cross-cuts all of the different kinds of message
1223 /// sends to determine what the underlying (statically known) type
1224 /// of the receiver will be; use \c getReceiverKind() to determine
1225 /// whether the message is a class or an instance method, whether it
1226 /// is a send to super or not, etc.
1228 /// \returns The type of the receiver.
1229 QualType getReceiverType() const;
1231 /// \brief Retrieve the Objective-C interface to which this message
1232 /// is being directed, if known.
1234 /// This routine cross-cuts all of the different kinds of message
1235 /// sends to determine what the underlying (statically known) type
1236 /// of the receiver will be; use \c getReceiverKind() to determine
1237 /// whether the message is a class or an instance method, whether it
1238 /// is a send to super or not, etc.
1240 /// \returns The Objective-C interface if known, otherwise NULL.
1241 ObjCInterfaceDecl *getReceiverInterface() const;
1243 /// \brief Retrieve the type referred to by 'super'.
1245 /// The returned type will either be an ObjCInterfaceType (for an
1246 /// class message to super) or an ObjCObjectPointerType that refers
1247 /// to a class (for an instance message to super);
1248 QualType getSuperType() const {
1249 if (getReceiverKind() == SuperInstance || getReceiverKind() == SuperClass)
1250 return QualType::getFromOpaquePtr(getReceiverPointer());
1255 void setSuper(SourceLocation Loc, QualType T, bool IsInstanceSuper) {
1256 Kind = IsInstanceSuper? SuperInstance : SuperClass;
1258 setReceiverPointer(T.getAsOpaquePtr());
1261 Selector getSelector() const;
1263 void setSelector(Selector S) {
1265 SelectorOrMethod = reinterpret_cast<uintptr_t>(S.getAsOpaquePtr());
1268 const ObjCMethodDecl *getMethodDecl() const {
1270 return reinterpret_cast<const ObjCMethodDecl *>(SelectorOrMethod);
1275 ObjCMethodDecl *getMethodDecl() {
1277 return reinterpret_cast<ObjCMethodDecl *>(SelectorOrMethod);
1282 void setMethodDecl(ObjCMethodDecl *MD) {
1284 SelectorOrMethod = reinterpret_cast<uintptr_t>(MD);
1287 ObjCMethodFamily getMethodFamily() const {
1288 if (HasMethod) return getMethodDecl()->getMethodFamily();
1289 return getSelector().getMethodFamily();
1292 /// \brief Return the number of actual arguments in this message,
1293 /// not counting the receiver.
1294 unsigned getNumArgs() const { return NumArgs; }
1296 /// \brief Retrieve the arguments to this message, not including the
1299 return reinterpret_cast<Expr **>(this + 1) + 1;
1301 const Expr * const *getArgs() const {
1302 return reinterpret_cast<const Expr * const *>(this + 1) + 1;
1305 /// getArg - Return the specified argument.
1306 Expr *getArg(unsigned Arg) {
1307 assert(Arg < NumArgs && "Arg access out of range!");
1308 return cast<Expr>(getArgs()[Arg]);
1310 const Expr *getArg(unsigned Arg) const {
1311 assert(Arg < NumArgs && "Arg access out of range!");
1312 return cast<Expr>(getArgs()[Arg]);
1314 /// setArg - Set the specified argument.
1315 void setArg(unsigned Arg, Expr *ArgExpr) {
1316 assert(Arg < NumArgs && "Arg access out of range!");
1317 getArgs()[Arg] = ArgExpr;
1320 /// isDelegateInitCall - Answers whether this message send has been
1321 /// tagged as a "delegate init call", i.e. a call to a method in the
1322 /// -init family on self from within an -init method implementation.
1323 bool isDelegateInitCall() const { return IsDelegateInitCall; }
1324 void setDelegateInitCall(bool isDelegate) { IsDelegateInitCall = isDelegate; }
1326 SourceLocation getLeftLoc() const { return LBracLoc; }
1327 SourceLocation getRightLoc() const { return RBracLoc; }
1329 SourceLocation getSelectorStartLoc() const {
1331 return getLocStart();
1332 return getSelectorLoc(0);
1334 SourceLocation getSelectorLoc(unsigned Index) const {
1335 assert(Index < getNumSelectorLocs() && "Index out of range!");
1336 if (hasStandardSelLocs())
1337 return getStandardSelectorLoc(Index, getSelector(),
1338 getSelLocsKind() == SelLoc_StandardWithSpace,
1339 llvm::makeArrayRef(const_cast<Expr**>(getArgs()),
1342 return getStoredSelLocs()[Index];
1345 void getSelectorLocs(SmallVectorImpl<SourceLocation> &SelLocs) const;
1347 unsigned getNumSelectorLocs() const {
1350 Selector Sel = getSelector();
1351 if (Sel.isUnarySelector())
1353 return Sel.getNumArgs();
1356 void setSourceRange(SourceRange R) {
1357 LBracLoc = R.getBegin();
1358 RBracLoc = R.getEnd();
1360 SourceLocation getLocStart() const LLVM_READONLY { return LBracLoc; }
1361 SourceLocation getLocEnd() const LLVM_READONLY { return RBracLoc; }
1363 static bool classof(const Stmt *T) {
1364 return T->getStmtClass() == ObjCMessageExprClass;
1368 child_range children();
1370 typedef ExprIterator arg_iterator;
1371 typedef ConstExprIterator const_arg_iterator;
1373 arg_iterator arg_begin() { return reinterpret_cast<Stmt **>(getArgs()); }
1374 arg_iterator arg_end() {
1375 return reinterpret_cast<Stmt **>(getArgs() + NumArgs);
1377 const_arg_iterator arg_begin() const {
1378 return reinterpret_cast<Stmt const * const*>(getArgs());
1380 const_arg_iterator arg_end() const {
1381 return reinterpret_cast<Stmt const * const*>(getArgs() + NumArgs);
1384 friend class ASTStmtReader;
1385 friend class ASTStmtWriter;
1388 /// ObjCIsaExpr - Represent X->isa and X.isa when X is an ObjC 'id' type.
1389 /// (similar in spirit to MemberExpr).
1390 class ObjCIsaExpr : public Expr {
1391 /// Base - the expression for the base object pointer.
1394 /// IsaMemberLoc - This is the location of the 'isa'.
1395 SourceLocation IsaMemberLoc;
1397 /// OpLoc - This is the location of '.' or '->'
1398 SourceLocation OpLoc;
1400 /// IsArrow - True if this is "X->F", false if this is "X.F".
1403 ObjCIsaExpr(Expr *base, bool isarrow, SourceLocation l, SourceLocation oploc,
1405 : Expr(ObjCIsaExprClass, ty, VK_LValue, OK_Ordinary,
1406 /*TypeDependent=*/false, base->isValueDependent(),
1407 base->isInstantiationDependent(),
1408 /*ContainsUnexpandedParameterPack=*/false),
1409 Base(base), IsaMemberLoc(l), OpLoc(oploc), IsArrow(isarrow) {}
1411 /// \brief Build an empty expression.
1412 explicit ObjCIsaExpr(EmptyShell Empty) : Expr(ObjCIsaExprClass, Empty) { }
1414 void setBase(Expr *E) { Base = E; }
1415 Expr *getBase() const { return cast<Expr>(Base); }
1417 bool isArrow() const { return IsArrow; }
1418 void setArrow(bool A) { IsArrow = A; }
1420 /// getMemberLoc - Return the location of the "member", in X->F, it is the
1421 /// location of 'F'.
1422 SourceLocation getIsaMemberLoc() const { return IsaMemberLoc; }
1423 void setIsaMemberLoc(SourceLocation L) { IsaMemberLoc = L; }
1425 SourceLocation getOpLoc() const { return OpLoc; }
1426 void setOpLoc(SourceLocation L) { OpLoc = L; }
1428 SourceLocation getLocStart() const LLVM_READONLY {
1429 return getBase()->getLocStart();
1432 SourceLocation getBaseLocEnd() const LLVM_READONLY {
1433 return getBase()->getLocEnd();
1436 SourceLocation getLocEnd() const LLVM_READONLY { return IsaMemberLoc; }
1438 SourceLocation getExprLoc() const LLVM_READONLY { return IsaMemberLoc; }
1440 static bool classof(const Stmt *T) {
1441 return T->getStmtClass() == ObjCIsaExprClass;
1445 child_range children() { return child_range(&Base, &Base+1); }
1449 /// ObjCIndirectCopyRestoreExpr - Represents the passing of a function
1450 /// argument by indirect copy-restore in ARC. This is used to support
1451 /// passing indirect arguments with the wrong lifetime, e.g. when
1452 /// passing the address of a __strong local variable to an 'out'
1453 /// parameter. This expression kind is only valid in an "argument"
1454 /// position to some sort of call expression.
1456 /// The parameter must have type 'pointer to T', and the argument must
1457 /// have type 'pointer to U', where T and U agree except possibly in
1458 /// qualification. If the argument value is null, then a null pointer
1459 /// is passed; otherwise it points to an object A, and:
1460 /// 1. A temporary object B of type T is initialized, either by
1461 /// zero-initialization (used when initializing an 'out' parameter)
1462 /// or copy-initialization (used when initializing an 'inout'
1464 /// 2. The address of the temporary is passed to the function.
1465 /// 3. If the call completes normally, A is move-assigned from B.
1466 /// 4. Finally, A is destroyed immediately.
1468 /// Currently 'T' must be a retainable object lifetime and must be
1469 /// __autoreleasing; this qualifier is ignored when initializing
1471 class ObjCIndirectCopyRestoreExpr : public Expr {
1474 // unsigned ObjCIndirectCopyRestoreBits.ShouldCopy : 1;
1476 friend class ASTReader;
1477 friend class ASTStmtReader;
1479 void setShouldCopy(bool shouldCopy) {
1480 ObjCIndirectCopyRestoreExprBits.ShouldCopy = shouldCopy;
1483 explicit ObjCIndirectCopyRestoreExpr(EmptyShell Empty)
1484 : Expr(ObjCIndirectCopyRestoreExprClass, Empty) { }
1487 ObjCIndirectCopyRestoreExpr(Expr *operand, QualType type, bool shouldCopy)
1488 : Expr(ObjCIndirectCopyRestoreExprClass, type, VK_LValue, OK_Ordinary,
1489 operand->isTypeDependent(), operand->isValueDependent(),
1490 operand->isInstantiationDependent(),
1491 operand->containsUnexpandedParameterPack()),
1493 setShouldCopy(shouldCopy);
1496 Expr *getSubExpr() { return cast<Expr>(Operand); }
1497 const Expr *getSubExpr() const { return cast<Expr>(Operand); }
1499 /// shouldCopy - True if we should do the 'copy' part of the
1500 /// copy-restore. If false, the temporary will be zero-initialized.
1501 bool shouldCopy() const { return ObjCIndirectCopyRestoreExprBits.ShouldCopy; }
1503 child_range children() { return child_range(&Operand, &Operand+1); }
1505 // Source locations are determined by the subexpression.
1506 SourceLocation getLocStart() const LLVM_READONLY {
1507 return Operand->getLocStart();
1509 SourceLocation getLocEnd() const LLVM_READONLY { return Operand->getLocEnd();}
1511 SourceLocation getExprLoc() const LLVM_READONLY {
1512 return getSubExpr()->getExprLoc();
1515 static bool classof(const Stmt *s) {
1516 return s->getStmtClass() == ObjCIndirectCopyRestoreExprClass;
1520 /// \brief An Objective-C "bridged" cast expression, which casts between
1521 /// Objective-C pointers and C pointers, transferring ownership in the process.
1524 /// NSString *str = (__bridge_transfer NSString *)CFCreateString();
1526 class ObjCBridgedCastExpr : public ExplicitCastExpr {
1527 SourceLocation LParenLoc;
1528 SourceLocation BridgeKeywordLoc;
1531 friend class ASTStmtReader;
1532 friend class ASTStmtWriter;
1535 ObjCBridgedCastExpr(SourceLocation LParenLoc, ObjCBridgeCastKind Kind,
1536 CastKind CK, SourceLocation BridgeKeywordLoc,
1537 TypeSourceInfo *TSInfo, Expr *Operand)
1538 : ExplicitCastExpr(ObjCBridgedCastExprClass, TSInfo->getType(), VK_RValue,
1539 CK, Operand, 0, TSInfo),
1540 LParenLoc(LParenLoc), BridgeKeywordLoc(BridgeKeywordLoc), Kind(Kind) { }
1542 /// \brief Construct an empty Objective-C bridged cast.
1543 explicit ObjCBridgedCastExpr(EmptyShell Shell)
1544 : ExplicitCastExpr(ObjCBridgedCastExprClass, Shell, 0) { }
1546 SourceLocation getLParenLoc() const { return LParenLoc; }
1548 /// \brief Determine which kind of bridge is being performed via this cast.
1549 ObjCBridgeCastKind getBridgeKind() const {
1550 return static_cast<ObjCBridgeCastKind>(Kind);
1553 /// \brief Retrieve the kind of bridge being performed as a string.
1554 StringRef getBridgeKindName() const;
1556 /// \brief The location of the bridge keyword.
1557 SourceLocation getBridgeKeywordLoc() const { return BridgeKeywordLoc; }
1559 SourceLocation getLocStart() const LLVM_READONLY { return LParenLoc; }
1560 SourceLocation getLocEnd() const LLVM_READONLY {
1561 return getSubExpr()->getLocEnd();
1564 static bool classof(const Stmt *T) {
1565 return T->getStmtClass() == ObjCBridgedCastExprClass;
1569 } // end namespace clang