1 //===--- ExprObjC.h - Classes for representing ObjC expressions -*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This file defines the ExprObjC interface and subclasses.
12 //===----------------------------------------------------------------------===//
14 #ifndef LLVM_CLANG_AST_EXPROBJC_H
15 #define LLVM_CLANG_AST_EXPROBJC_H
17 #include "clang/AST/DeclObjC.h"
18 #include "clang/AST/Expr.h"
19 #include "clang/AST/SelectorLocationsKind.h"
20 #include "clang/Basic/IdentifierTable.h"
21 #include "llvm/Support/Compiler.h"
27 /// ObjCStringLiteral, used for Objective-C string literals
29 class ObjCStringLiteral : public Expr {
33 ObjCStringLiteral(StringLiteral *SL, QualType T, SourceLocation L)
34 : Expr(ObjCStringLiteralClass, T, VK_RValue, OK_Ordinary, false, false,
36 String(SL), AtLoc(L) {}
37 explicit ObjCStringLiteral(EmptyShell Empty)
38 : Expr(ObjCStringLiteralClass, Empty) {}
40 StringLiteral *getString() { return cast<StringLiteral>(String); }
41 const StringLiteral *getString() const { return cast<StringLiteral>(String); }
42 void setString(StringLiteral *S) { String = S; }
44 SourceLocation getAtLoc() const { return AtLoc; }
45 void setAtLoc(SourceLocation L) { AtLoc = L; }
47 SourceRange getSourceRange() const LLVM_READONLY {
48 return SourceRange(AtLoc, String->getLocEnd());
51 static bool classof(const Stmt *T) {
52 return T->getStmtClass() == ObjCStringLiteralClass;
56 child_range children() { return child_range(&String, &String+1); }
59 /// ObjCBoolLiteralExpr - Objective-C Boolean Literal.
61 class ObjCBoolLiteralExpr : public Expr {
65 ObjCBoolLiteralExpr(bool val, QualType Ty, SourceLocation l) :
66 Expr(ObjCBoolLiteralExprClass, Ty, VK_RValue, OK_Ordinary, false, false,
67 false, false), Value(val), Loc(l) {}
69 explicit ObjCBoolLiteralExpr(EmptyShell Empty)
70 : Expr(ObjCBoolLiteralExprClass, Empty) { }
72 bool getValue() const { return Value; }
73 void setValue(bool V) { Value = V; }
75 SourceRange getSourceRange() const LLVM_READONLY { return SourceRange(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 SourceRange getSourceRange() const LLVM_READONLY {
119 static bool classof(const Stmt *T) {
120 return T->getStmtClass() == ObjCBoxedExprClass;
124 child_range children() { return child_range(&SubExpr, &SubExpr+1); }
126 friend class ASTStmtReader;
129 /// ObjCArrayLiteral - used for objective-c array containers; as in:
130 /// @[@"Hello", NSApp, [NSNumber numberWithInt:42]];
131 class ObjCArrayLiteral : public Expr {
132 unsigned NumElements;
134 ObjCMethodDecl *ArrayWithObjectsMethod;
136 ObjCArrayLiteral(llvm::ArrayRef<Expr *> Elements,
137 QualType T, ObjCMethodDecl * Method,
140 explicit ObjCArrayLiteral(EmptyShell Empty, unsigned NumElements)
141 : Expr(ObjCArrayLiteralClass, Empty), NumElements(NumElements) {}
144 static ObjCArrayLiteral *Create(ASTContext &C,
145 llvm::ArrayRef<Expr *> Elements,
146 QualType T, ObjCMethodDecl * Method,
149 static ObjCArrayLiteral *CreateEmpty(ASTContext &C, unsigned NumElements);
151 SourceRange getSourceRange() const LLVM_READONLY { return Range; }
153 static bool classof(const Stmt *T) {
154 return T->getStmtClass() == ObjCArrayLiteralClass;
157 /// \brief Retrieve elements of array of literals.
158 Expr **getElements() { return reinterpret_cast<Expr **>(this + 1); }
160 /// \brief Retrieve elements of array of literals.
161 const Expr * const *getElements() const {
162 return reinterpret_cast<const Expr * const*>(this + 1);
165 /// getNumElements - Return number of elements of objective-c array literal.
166 unsigned getNumElements() const { return NumElements; }
168 /// getExpr - Return the Expr at the specified index.
169 Expr *getElement(unsigned Index) {
170 assert((Index < NumElements) && "Arg access out of range!");
171 return cast<Expr>(getElements()[Index]);
173 const Expr *getElement(unsigned Index) const {
174 assert((Index < NumElements) && "Arg access out of range!");
175 return cast<Expr>(getElements()[Index]);
178 ObjCMethodDecl *getArrayWithObjectsMethod() const {
179 return ArrayWithObjectsMethod;
183 child_range children() {
184 return child_range((Stmt **)getElements(),
185 (Stmt **)getElements() + NumElements);
188 friend class ASTStmtReader;
191 /// \brief An element in an Objective-C dictionary literal.
193 struct ObjCDictionaryElement {
194 /// \brief The key for the dictionary element.
197 /// \brief The value of the dictionary element.
200 /// \brief The location of the ellipsis, if this is a pack expansion.
201 SourceLocation EllipsisLoc;
203 /// \brief The number of elements this pack expansion will expand to, if
204 /// this is a pack expansion and is known.
205 llvm::Optional<unsigned> NumExpansions;
207 /// \brief Determines whether this dictionary element is a pack expansion.
208 bool isPackExpansion() const { return EllipsisLoc.isValid(); }
211 /// ObjCDictionaryLiteral - AST node to represent objective-c dictionary
212 /// literals; as in: @{@"name" : NSUserName(), @"date" : [NSDate date] };
213 class ObjCDictionaryLiteral : public Expr {
214 /// \brief Key/value pair used to store the key and value of a given element.
216 /// Objects of this type are stored directly after the expression.
217 struct KeyValuePair {
222 /// \brief Data that describes an element that is a pack expansion, used if any
223 /// of the elements in the dictionary literal are pack expansions.
224 struct ExpansionData {
225 /// \brief The location of the ellipsis, if this element is a pack
227 SourceLocation EllipsisLoc;
229 /// \brief If non-zero, the number of elements that this pack
230 /// expansion will expand to (+1).
231 unsigned NumExpansionsPlusOne;
234 /// \brief The number of elements in this dictionary literal.
235 unsigned NumElements : 31;
237 /// \brief Determine whether this dictionary literal has any pack expansions.
239 /// If the dictionary literal has pack expansions, then there will
240 /// be an array of pack expansion data following the array of
241 /// key/value pairs, which provide the locations of the ellipses (if
242 /// any) and number of elements in the expansion (if known). If
243 /// there are no pack expansions, we optimize away this storage.
244 unsigned HasPackExpansions : 1;
247 ObjCMethodDecl *DictWithObjectsMethod;
249 ObjCDictionaryLiteral(ArrayRef<ObjCDictionaryElement> VK,
250 bool HasPackExpansions,
251 QualType T, ObjCMethodDecl *method,
254 explicit ObjCDictionaryLiteral(EmptyShell Empty, unsigned NumElements,
255 bool HasPackExpansions)
256 : Expr(ObjCDictionaryLiteralClass, Empty), NumElements(NumElements),
257 HasPackExpansions(HasPackExpansions) {}
259 KeyValuePair *getKeyValues() {
260 return reinterpret_cast<KeyValuePair *>(this + 1);
263 const KeyValuePair *getKeyValues() const {
264 return reinterpret_cast<const KeyValuePair *>(this + 1);
267 ExpansionData *getExpansionData() {
268 if (!HasPackExpansions)
271 return reinterpret_cast<ExpansionData *>(getKeyValues() + NumElements);
274 const ExpansionData *getExpansionData() const {
275 if (!HasPackExpansions)
278 return reinterpret_cast<const ExpansionData *>(getKeyValues()+NumElements);
282 static ObjCDictionaryLiteral *Create(ASTContext &C,
283 ArrayRef<ObjCDictionaryElement> VK,
284 bool HasPackExpansions,
285 QualType T, ObjCMethodDecl *method,
288 static ObjCDictionaryLiteral *CreateEmpty(ASTContext &C,
289 unsigned NumElements,
290 bool HasPackExpansions);
292 /// getNumElements - Return number of elements of objective-c dictionary
294 unsigned getNumElements() const { return NumElements; }
296 ObjCDictionaryElement getKeyValueElement(unsigned Index) const {
297 assert((Index < NumElements) && "Arg access out of range!");
298 const KeyValuePair &KV = getKeyValues()[Index];
299 ObjCDictionaryElement Result = { KV.Key, KV.Value, SourceLocation(),
300 llvm::Optional<unsigned>() };
301 if (HasPackExpansions) {
302 const ExpansionData &Expansion = getExpansionData()[Index];
303 Result.EllipsisLoc = Expansion.EllipsisLoc;
304 if (Expansion.NumExpansionsPlusOne > 0)
305 Result.NumExpansions = Expansion.NumExpansionsPlusOne - 1;
310 ObjCMethodDecl *getDictWithObjectsMethod() const
311 { return DictWithObjectsMethod; }
313 SourceRange getSourceRange() const LLVM_READONLY { return Range; }
315 static bool classof(const Stmt *T) {
316 return T->getStmtClass() == ObjCDictionaryLiteralClass;
320 child_range children() {
321 // Note: we're taking advantage of the layout of the KeyValuePair struct
322 // here. If that struct changes, this code will need to change as well.
323 return child_range(reinterpret_cast<Stmt **>(this + 1),
324 reinterpret_cast<Stmt **>(this + 1) + NumElements * 2);
327 friend class ASTStmtReader;
328 friend class ASTStmtWriter;
332 /// ObjCEncodeExpr, used for \@encode in Objective-C. \@encode has the same
333 /// type and behavior as StringLiteral except that the string initializer is
334 /// obtained from ASTContext with the encoding type as an argument.
335 class ObjCEncodeExpr : public Expr {
336 TypeSourceInfo *EncodedType;
337 SourceLocation AtLoc, RParenLoc;
339 ObjCEncodeExpr(QualType T, TypeSourceInfo *EncodedType,
340 SourceLocation at, SourceLocation rp)
341 : Expr(ObjCEncodeExprClass, T, VK_LValue, OK_Ordinary,
342 EncodedType->getType()->isDependentType(),
343 EncodedType->getType()->isDependentType(),
344 EncodedType->getType()->isInstantiationDependentType(),
345 EncodedType->getType()->containsUnexpandedParameterPack()),
346 EncodedType(EncodedType), AtLoc(at), RParenLoc(rp) {}
348 explicit ObjCEncodeExpr(EmptyShell Empty) : Expr(ObjCEncodeExprClass, Empty){}
351 SourceLocation getAtLoc() const { return AtLoc; }
352 void setAtLoc(SourceLocation L) { AtLoc = L; }
353 SourceLocation getRParenLoc() const { return RParenLoc; }
354 void setRParenLoc(SourceLocation L) { RParenLoc = L; }
356 QualType getEncodedType() const { return EncodedType->getType(); }
358 TypeSourceInfo *getEncodedTypeSourceInfo() const { return EncodedType; }
359 void setEncodedTypeSourceInfo(TypeSourceInfo *EncType) {
360 EncodedType = EncType;
363 SourceRange getSourceRange() const LLVM_READONLY {
364 return SourceRange(AtLoc, RParenLoc);
367 static bool classof(const Stmt *T) {
368 return T->getStmtClass() == ObjCEncodeExprClass;
372 child_range children() { return child_range(); }
375 /// ObjCSelectorExpr used for \@selector in Objective-C.
376 class ObjCSelectorExpr : public Expr {
378 SourceLocation AtLoc, RParenLoc;
380 ObjCSelectorExpr(QualType T, Selector selInfo,
381 SourceLocation at, SourceLocation rp)
382 : Expr(ObjCSelectorExprClass, T, VK_RValue, OK_Ordinary, false, false,
384 SelName(selInfo), AtLoc(at), RParenLoc(rp){}
385 explicit ObjCSelectorExpr(EmptyShell Empty)
386 : Expr(ObjCSelectorExprClass, Empty) {}
388 Selector getSelector() const { return SelName; }
389 void setSelector(Selector S) { SelName = S; }
391 SourceLocation getAtLoc() const { return AtLoc; }
392 SourceLocation getRParenLoc() const { return RParenLoc; }
393 void setAtLoc(SourceLocation L) { AtLoc = L; }
394 void setRParenLoc(SourceLocation L) { RParenLoc = L; }
396 SourceRange getSourceRange() const LLVM_READONLY {
397 return SourceRange(AtLoc, RParenLoc);
400 /// getNumArgs - Return the number of actual arguments to this call.
401 unsigned getNumArgs() const { return SelName.getNumArgs(); }
403 static bool classof(const Stmt *T) {
404 return T->getStmtClass() == ObjCSelectorExprClass;
408 child_range children() { return child_range(); }
411 /// ObjCProtocolExpr used for protocol expression in Objective-C. This is used
412 /// as: @protocol(foo), as in:
413 /// obj conformsToProtocol:@protocol(foo)]
414 /// The return type is "Protocol*".
415 class ObjCProtocolExpr : public Expr {
416 ObjCProtocolDecl *TheProtocol;
417 SourceLocation AtLoc, ProtoLoc, RParenLoc;
419 ObjCProtocolExpr(QualType T, ObjCProtocolDecl *protocol,
420 SourceLocation at, SourceLocation protoLoc, SourceLocation rp)
421 : Expr(ObjCProtocolExprClass, T, VK_RValue, OK_Ordinary, false, false,
423 TheProtocol(protocol), AtLoc(at), ProtoLoc(protoLoc), RParenLoc(rp) {}
424 explicit ObjCProtocolExpr(EmptyShell Empty)
425 : Expr(ObjCProtocolExprClass, Empty) {}
427 ObjCProtocolDecl *getProtocol() const { return TheProtocol; }
428 void setProtocol(ObjCProtocolDecl *P) { TheProtocol = P; }
430 SourceLocation getProtocolIdLoc() const { return ProtoLoc; }
431 SourceLocation getAtLoc() const { return AtLoc; }
432 SourceLocation getRParenLoc() const { return RParenLoc; }
433 void setAtLoc(SourceLocation L) { AtLoc = L; }
434 void setRParenLoc(SourceLocation L) { RParenLoc = L; }
436 SourceRange getSourceRange() const LLVM_READONLY {
437 return SourceRange(AtLoc, RParenLoc);
440 static bool classof(const Stmt *T) {
441 return T->getStmtClass() == ObjCProtocolExprClass;
445 child_range children() { return child_range(); }
447 friend class ASTStmtReader;
448 friend class ASTStmtWriter;
451 /// ObjCIvarRefExpr - A reference to an ObjC instance variable.
452 class ObjCIvarRefExpr : public Expr {
456 bool IsArrow:1; // True if this is "X->F", false if this is "X.F".
457 bool IsFreeIvar:1; // True if ivar reference has no base (self assumed).
460 ObjCIvarRefExpr(ObjCIvarDecl *d, QualType t,
461 SourceLocation l, Expr *base,
462 bool arrow = false, bool freeIvar = false) :
463 Expr(ObjCIvarRefExprClass, t, VK_LValue, OK_Ordinary,
464 /*TypeDependent=*/false, base->isValueDependent(),
465 base->isInstantiationDependent(),
466 base->containsUnexpandedParameterPack()),
467 D(d), Base(base), Loc(l), IsArrow(arrow), IsFreeIvar(freeIvar) {}
469 explicit ObjCIvarRefExpr(EmptyShell Empty)
470 : Expr(ObjCIvarRefExprClass, Empty) {}
472 ObjCIvarDecl *getDecl() { return D; }
473 const ObjCIvarDecl *getDecl() const { return D; }
474 void setDecl(ObjCIvarDecl *d) { D = d; }
476 const Expr *getBase() const { return cast<Expr>(Base); }
477 Expr *getBase() { return cast<Expr>(Base); }
478 void setBase(Expr * base) { Base = base; }
480 bool isArrow() const { return IsArrow; }
481 bool isFreeIvar() const { return IsFreeIvar; }
482 void setIsArrow(bool A) { IsArrow = A; }
483 void setIsFreeIvar(bool A) { IsFreeIvar = A; }
485 SourceLocation getLocation() const { return Loc; }
486 void setLocation(SourceLocation L) { Loc = L; }
488 SourceRange getSourceRange() const LLVM_READONLY {
489 return isFreeIvar() ? SourceRange(Loc)
490 : SourceRange(getBase()->getLocStart(), Loc);
493 static bool classof(const Stmt *T) {
494 return T->getStmtClass() == ObjCIvarRefExprClass;
498 child_range children() { return child_range(&Base, &Base+1); }
501 /// ObjCPropertyRefExpr - A dot-syntax expression to access an ObjC
503 class ObjCPropertyRefExpr : public Expr {
505 /// If the bool is true, this is an implicit property reference; the
506 /// pointer is an (optional) ObjCMethodDecl and Setter may be set.
507 /// if the bool is false, this is an explicit property reference;
508 /// the pointer is an ObjCPropertyDecl and Setter is always null.
509 llvm::PointerIntPair<NamedDecl*, 1, bool> PropertyOrGetter;
511 /// \brief Indicates whether the property reference will result in a message
512 /// to the getter, the setter, or both.
513 /// This applies to both implicit and explicit property references.
514 enum MethodRefFlags {
516 MethodRef_Getter = 0x1,
517 MethodRef_Setter = 0x2
520 /// \brief Contains the Setter method pointer and MethodRefFlags bit flags.
521 llvm::PointerIntPair<ObjCMethodDecl *, 2, unsigned> SetterAndMethodRefFlags;
523 // FIXME: Maybe we should store the property identifier here,
524 // because it's not rederivable from the other data when there's an
525 // implicit property with no getter (because the 'foo' -> 'setFoo:'
526 // transformation is lossy on the first character).
528 SourceLocation IdLoc;
530 /// \brief When the receiver in property access is 'super', this is
531 /// the location of the 'super' keyword. When it's an interface,
532 /// this is that interface.
533 SourceLocation ReceiverLoc;
534 llvm::PointerUnion3<Stmt*, const Type*, ObjCInterfaceDecl*> Receiver;
537 ObjCPropertyRefExpr(ObjCPropertyDecl *PD, QualType t,
538 ExprValueKind VK, ExprObjectKind OK,
539 SourceLocation l, Expr *base)
540 : Expr(ObjCPropertyRefExprClass, t, VK, OK,
541 /*TypeDependent=*/false, base->isValueDependent(),
542 base->isInstantiationDependent(),
543 base->containsUnexpandedParameterPack()),
544 PropertyOrGetter(PD, false), SetterAndMethodRefFlags(),
545 IdLoc(l), ReceiverLoc(), Receiver(base) {
546 assert(t->isSpecificPlaceholderType(BuiltinType::PseudoObject));
549 ObjCPropertyRefExpr(ObjCPropertyDecl *PD, QualType t,
550 ExprValueKind VK, ExprObjectKind OK,
551 SourceLocation l, SourceLocation sl, QualType st)
552 : Expr(ObjCPropertyRefExprClass, t, VK, OK,
553 /*TypeDependent=*/false, false, st->isInstantiationDependentType(),
554 st->containsUnexpandedParameterPack()),
555 PropertyOrGetter(PD, false), SetterAndMethodRefFlags(),
556 IdLoc(l), ReceiverLoc(sl), Receiver(st.getTypePtr()) {
557 assert(t->isSpecificPlaceholderType(BuiltinType::PseudoObject));
560 ObjCPropertyRefExpr(ObjCMethodDecl *Getter, ObjCMethodDecl *Setter,
561 QualType T, ExprValueKind VK, ExprObjectKind OK,
562 SourceLocation IdLoc, Expr *Base)
563 : Expr(ObjCPropertyRefExprClass, T, VK, OK, false,
564 Base->isValueDependent(), Base->isInstantiationDependent(),
565 Base->containsUnexpandedParameterPack()),
566 PropertyOrGetter(Getter, true), SetterAndMethodRefFlags(Setter, 0),
567 IdLoc(IdLoc), ReceiverLoc(), Receiver(Base) {
568 assert(T->isSpecificPlaceholderType(BuiltinType::PseudoObject));
571 ObjCPropertyRefExpr(ObjCMethodDecl *Getter, ObjCMethodDecl *Setter,
572 QualType T, ExprValueKind VK, ExprObjectKind OK,
573 SourceLocation IdLoc,
574 SourceLocation SuperLoc, QualType SuperTy)
575 : Expr(ObjCPropertyRefExprClass, T, VK, OK, false, false, false, false),
576 PropertyOrGetter(Getter, true), SetterAndMethodRefFlags(Setter, 0),
577 IdLoc(IdLoc), ReceiverLoc(SuperLoc), Receiver(SuperTy.getTypePtr()) {
578 assert(T->isSpecificPlaceholderType(BuiltinType::PseudoObject));
581 ObjCPropertyRefExpr(ObjCMethodDecl *Getter, ObjCMethodDecl *Setter,
582 QualType T, ExprValueKind VK, ExprObjectKind OK,
583 SourceLocation IdLoc,
584 SourceLocation ReceiverLoc, ObjCInterfaceDecl *Receiver)
585 : Expr(ObjCPropertyRefExprClass, T, VK, OK, false, false, false, false),
586 PropertyOrGetter(Getter, true), SetterAndMethodRefFlags(Setter, 0),
587 IdLoc(IdLoc), ReceiverLoc(ReceiverLoc), Receiver(Receiver) {
588 assert(T->isSpecificPlaceholderType(BuiltinType::PseudoObject));
591 explicit ObjCPropertyRefExpr(EmptyShell Empty)
592 : Expr(ObjCPropertyRefExprClass, Empty) {}
594 bool isImplicitProperty() const { return PropertyOrGetter.getInt(); }
595 bool isExplicitProperty() const { return !PropertyOrGetter.getInt(); }
597 ObjCPropertyDecl *getExplicitProperty() const {
598 assert(!isImplicitProperty());
599 return cast<ObjCPropertyDecl>(PropertyOrGetter.getPointer());
602 ObjCMethodDecl *getImplicitPropertyGetter() const {
603 assert(isImplicitProperty());
604 return cast_or_null<ObjCMethodDecl>(PropertyOrGetter.getPointer());
607 ObjCMethodDecl *getImplicitPropertySetter() const {
608 assert(isImplicitProperty());
609 return SetterAndMethodRefFlags.getPointer();
612 Selector getGetterSelector() const {
613 if (isImplicitProperty())
614 return getImplicitPropertyGetter()->getSelector();
615 return getExplicitProperty()->getGetterName();
618 Selector getSetterSelector() const {
619 if (isImplicitProperty())
620 return getImplicitPropertySetter()->getSelector();
621 return getExplicitProperty()->getSetterName();
624 /// \brief True if the property reference will result in a message to the
626 /// This applies to both implicit and explicit property references.
627 bool isMessagingGetter() const {
628 return SetterAndMethodRefFlags.getInt() & MethodRef_Getter;
631 /// \brief True if the property reference will result in a message to the
633 /// This applies to both implicit and explicit property references.
634 bool isMessagingSetter() const {
635 return SetterAndMethodRefFlags.getInt() & MethodRef_Setter;
638 void setIsMessagingGetter(bool val = true) {
639 setMethodRefFlag(MethodRef_Getter, val);
642 void setIsMessagingSetter(bool val = true) {
643 setMethodRefFlag(MethodRef_Setter, val);
646 const Expr *getBase() const {
647 return cast<Expr>(Receiver.get<Stmt*>());
650 return cast<Expr>(Receiver.get<Stmt*>());
653 SourceLocation getLocation() const { return IdLoc; }
655 SourceLocation getReceiverLocation() const { return ReceiverLoc; }
656 QualType getSuperReceiverType() const {
657 return QualType(Receiver.get<const Type*>(), 0);
659 QualType getGetterResultType() const {
661 if (isExplicitProperty()) {
662 const ObjCPropertyDecl *PDecl = getExplicitProperty();
663 if (const ObjCMethodDecl *Getter = PDecl->getGetterMethodDecl())
664 ResultType = Getter->getResultType();
666 ResultType = PDecl->getType();
668 const ObjCMethodDecl *Getter = getImplicitPropertyGetter();
670 ResultType = Getter->getResultType(); // with reference!
675 QualType getSetterArgType() const {
677 if (isImplicitProperty()) {
678 const ObjCMethodDecl *Setter = getImplicitPropertySetter();
679 ObjCMethodDecl::param_const_iterator P = Setter->param_begin();
680 ArgType = (*P)->getType();
682 if (ObjCPropertyDecl *PDecl = getExplicitProperty())
683 if (const ObjCMethodDecl *Setter = PDecl->getSetterMethodDecl()) {
684 ObjCMethodDecl::param_const_iterator P = Setter->param_begin();
685 ArgType = (*P)->getType();
687 if (ArgType.isNull())
693 ObjCInterfaceDecl *getClassReceiver() const {
694 return Receiver.get<ObjCInterfaceDecl*>();
696 bool isObjectReceiver() const { return Receiver.is<Stmt*>(); }
697 bool isSuperReceiver() const { return Receiver.is<const Type*>(); }
698 bool isClassReceiver() const { return Receiver.is<ObjCInterfaceDecl*>(); }
700 SourceRange getSourceRange() const LLVM_READONLY {
701 return SourceRange((isObjectReceiver() ? getBase()->getLocStart()
702 : getReceiverLocation()),
706 static bool classof(const Stmt *T) {
707 return T->getStmtClass() == ObjCPropertyRefExprClass;
711 child_range children() {
712 if (Receiver.is<Stmt*>()) {
713 Stmt **begin = reinterpret_cast<Stmt**>(&Receiver); // hack!
714 return child_range(begin, begin+1);
716 return child_range();
720 friend class ASTStmtReader;
721 friend class ASTStmtWriter;
722 void setExplicitProperty(ObjCPropertyDecl *D, unsigned methRefFlags) {
723 PropertyOrGetter.setPointer(D);
724 PropertyOrGetter.setInt(false);
725 SetterAndMethodRefFlags.setPointer(0);
726 SetterAndMethodRefFlags.setInt(methRefFlags);
728 void setImplicitProperty(ObjCMethodDecl *Getter, ObjCMethodDecl *Setter,
729 unsigned methRefFlags) {
730 PropertyOrGetter.setPointer(Getter);
731 PropertyOrGetter.setInt(true);
732 SetterAndMethodRefFlags.setPointer(Setter);
733 SetterAndMethodRefFlags.setInt(methRefFlags);
735 void setBase(Expr *Base) { Receiver = Base; }
736 void setSuperReceiver(QualType T) { Receiver = T.getTypePtr(); }
737 void setClassReceiver(ObjCInterfaceDecl *D) { Receiver = D; }
739 void setLocation(SourceLocation L) { IdLoc = L; }
740 void setReceiverLocation(SourceLocation Loc) { ReceiverLoc = Loc; }
742 void setMethodRefFlag(MethodRefFlags flag, bool val) {
743 unsigned f = SetterAndMethodRefFlags.getInt();
748 SetterAndMethodRefFlags.setInt(f);
752 /// ObjCSubscriptRefExpr - used for array and dictionary subscripting.
753 /// array[4] = array[3]; dictionary[key] = dictionary[alt_key];
755 class ObjCSubscriptRefExpr : public Expr {
756 // Location of ']' in an indexing expression.
757 SourceLocation RBracket;
758 // array/dictionary base expression.
759 // for arrays, this is a numeric expression. For dictionaries, this is
760 // an objective-c object pointer expression.
761 enum { BASE, KEY, END_EXPR };
762 Stmt* SubExprs[END_EXPR];
764 ObjCMethodDecl *GetAtIndexMethodDecl;
766 // For immutable objects this is null. When ObjCSubscriptRefExpr is to read
767 // an indexed object this is null too.
768 ObjCMethodDecl *SetAtIndexMethodDecl;
772 ObjCSubscriptRefExpr(Expr *base, Expr *key, QualType T,
773 ExprValueKind VK, ExprObjectKind OK,
774 ObjCMethodDecl *getMethod,
775 ObjCMethodDecl *setMethod, SourceLocation RB)
776 : Expr(ObjCSubscriptRefExprClass, T, VK, OK,
777 base->isTypeDependent() || key->isTypeDependent(),
778 base->isValueDependent() || key->isValueDependent(),
779 base->isInstantiationDependent() || key->isInstantiationDependent(),
780 (base->containsUnexpandedParameterPack() ||
781 key->containsUnexpandedParameterPack())),
783 GetAtIndexMethodDecl(getMethod),
784 SetAtIndexMethodDecl(setMethod)
785 {SubExprs[BASE] = base; SubExprs[KEY] = key;}
787 explicit ObjCSubscriptRefExpr(EmptyShell Empty)
788 : Expr(ObjCSubscriptRefExprClass, Empty) {}
790 static ObjCSubscriptRefExpr *Create(ASTContext &C,
792 Expr *key, QualType T,
793 ObjCMethodDecl *getMethod,
794 ObjCMethodDecl *setMethod,
797 SourceLocation getRBracket() const { return RBracket; }
798 void setRBracket(SourceLocation RB) { RBracket = RB; }
799 SourceRange getSourceRange() const LLVM_READONLY {
800 return SourceRange(SubExprs[BASE]->getLocStart(), RBracket);
803 static bool classof(const Stmt *T) {
804 return T->getStmtClass() == ObjCSubscriptRefExprClass;
807 Expr *getBaseExpr() const { return cast<Expr>(SubExprs[BASE]); }
808 void setBaseExpr(Stmt *S) { SubExprs[BASE] = S; }
810 Expr *getKeyExpr() const { return cast<Expr>(SubExprs[KEY]); }
811 void setKeyExpr(Stmt *S) { SubExprs[KEY] = S; }
813 ObjCMethodDecl *getAtIndexMethodDecl() const {
814 return GetAtIndexMethodDecl;
817 ObjCMethodDecl *setAtIndexMethodDecl() const {
818 return SetAtIndexMethodDecl;
821 bool isArraySubscriptRefExpr() const {
822 return getKeyExpr()->getType()->isIntegralOrEnumerationType();
825 child_range children() {
826 return child_range(SubExprs, SubExprs+END_EXPR);
829 friend class ASTStmtReader;
833 /// \brief An expression that sends a message to the given Objective-C
836 /// The following contains two message send expressions:
839 /// [[NSString alloc] initWithString:@"Hello"]
842 /// The innermost message send invokes the "alloc" class method on the
843 /// NSString class, while the outermost message send invokes the
844 /// "initWithString" instance method on the object returned from
845 /// NSString's "alloc". In all, an Objective-C message send can take
846 /// on four different (although related) forms:
848 /// 1. Send to an object instance.
849 /// 2. Send to a class.
850 /// 3. Send to the superclass instance of the current class.
851 /// 4. Send to the superclass of the current class.
853 /// All four kinds of message sends are modeled by the ObjCMessageExpr
854 /// class, and can be distinguished via \c getReceiverKind(). Example:
856 class ObjCMessageExpr : public Expr {
857 /// \brief Stores either the selector that this message is sending
858 /// to (when \c HasMethod is zero) or an \c ObjCMethodDecl pointer
859 /// referring to the method that we type-checked against.
860 uintptr_t SelectorOrMethod;
862 enum { NumArgsBitWidth = 16 };
864 /// \brief The number of arguments in the message send, not
865 /// including the receiver.
866 unsigned NumArgs : NumArgsBitWidth;
868 void setNumArgs(unsigned Num) {
869 assert((Num >> NumArgsBitWidth) == 0 && "Num of args is out of range!");
873 /// \brief The kind of message send this is, which is one of the
874 /// ReceiverKind values.
876 /// We pad this out to a byte to avoid excessive masking and shifting.
879 /// \brief Whether we have an actual method prototype in \c
880 /// SelectorOrMethod.
882 /// When non-zero, we have a method declaration; otherwise, we just
884 unsigned HasMethod : 1;
886 /// \brief Whether this message send is a "delegate init call",
887 /// i.e. a call of an init method on self from within an init method.
888 unsigned IsDelegateInitCall : 1;
890 /// \brief Whether this message send was implicitly generated by
891 /// the implementation rather than explicitly written by the user.
892 unsigned IsImplicit : 1;
894 /// \brief Whether the locations of the selector identifiers are in a
895 /// "standard" position, a enum SelectorLocationsKind.
896 unsigned SelLocsKind : 2;
898 /// \brief When the message expression is a send to 'super', this is
899 /// the location of the 'super' keyword.
900 SourceLocation SuperLoc;
902 /// \brief The source locations of the open and close square
903 /// brackets ('[' and ']', respectively).
904 SourceLocation LBracLoc, RBracLoc;
906 ObjCMessageExpr(EmptyShell Empty, unsigned NumArgs)
907 : Expr(ObjCMessageExprClass, Empty), SelectorOrMethod(0), Kind(0),
908 HasMethod(0), IsDelegateInitCall(0), IsImplicit(0), SelLocsKind(0) {
912 ObjCMessageExpr(QualType T, ExprValueKind VK,
913 SourceLocation LBracLoc,
914 SourceLocation SuperLoc,
915 bool IsInstanceSuper,
918 ArrayRef<SourceLocation> SelLocs,
919 SelectorLocationsKind SelLocsK,
920 ObjCMethodDecl *Method,
921 ArrayRef<Expr *> Args,
922 SourceLocation RBracLoc,
924 ObjCMessageExpr(QualType T, ExprValueKind VK,
925 SourceLocation LBracLoc,
926 TypeSourceInfo *Receiver,
928 ArrayRef<SourceLocation> SelLocs,
929 SelectorLocationsKind SelLocsK,
930 ObjCMethodDecl *Method,
931 ArrayRef<Expr *> Args,
932 SourceLocation RBracLoc,
934 ObjCMessageExpr(QualType T, ExprValueKind VK,
935 SourceLocation LBracLoc,
938 ArrayRef<SourceLocation> SelLocs,
939 SelectorLocationsKind SelLocsK,
940 ObjCMethodDecl *Method,
941 ArrayRef<Expr *> Args,
942 SourceLocation RBracLoc,
945 void initArgsAndSelLocs(ArrayRef<Expr *> Args,
946 ArrayRef<SourceLocation> SelLocs,
947 SelectorLocationsKind SelLocsK);
949 /// \brief Retrieve the pointer value of the message receiver.
950 void *getReceiverPointer() const {
951 return *const_cast<void **>(
952 reinterpret_cast<const void * const*>(this + 1));
955 /// \brief Set the pointer value of the message receiver.
956 void setReceiverPointer(void *Value) {
957 *reinterpret_cast<void **>(this + 1) = Value;
960 SelectorLocationsKind getSelLocsKind() const {
961 return (SelectorLocationsKind)SelLocsKind;
963 bool hasStandardSelLocs() const {
964 return getSelLocsKind() != SelLoc_NonStandard;
967 /// \brief Get a pointer to the stored selector identifiers locations array.
968 /// No locations will be stored if HasStandardSelLocs is true.
969 SourceLocation *getStoredSelLocs() {
970 return reinterpret_cast<SourceLocation*>(getArgs() + getNumArgs());
972 const SourceLocation *getStoredSelLocs() const {
973 return reinterpret_cast<const SourceLocation*>(getArgs() + getNumArgs());
976 /// \brief Get the number of stored selector identifiers locations.
977 /// No locations will be stored if HasStandardSelLocs is true.
978 unsigned getNumStoredSelLocs() const {
979 if (hasStandardSelLocs())
981 return getNumSelectorLocs();
984 static ObjCMessageExpr *alloc(ASTContext &C,
985 ArrayRef<Expr *> Args,
986 SourceLocation RBraceLoc,
987 ArrayRef<SourceLocation> SelLocs,
989 SelectorLocationsKind &SelLocsK);
990 static ObjCMessageExpr *alloc(ASTContext &C,
992 unsigned NumStoredSelLocs);
995 /// \brief The kind of receiver this message is sending to.
997 /// \brief The receiver is a class.
999 /// \brief The receiver is an object instance.
1001 /// \brief The receiver is a superclass.
1003 /// \brief The receiver is the instance of the superclass object.
1007 /// \brief Create a message send to super.
1009 /// \param Context The ASTContext in which this expression will be created.
1011 /// \param T The result type of this message.
1013 /// \param VK The value kind of this message. A message returning
1014 /// a l-value or r-value reference will be an l-value or x-value,
1017 /// \param LBracLoc The location of the open square bracket '['.
1019 /// \param SuperLoc The location of the "super" keyword.
1021 /// \param IsInstanceSuper Whether this is an instance "super"
1022 /// message (otherwise, it's a class "super" message).
1024 /// \param Sel The selector used to determine which method gets called.
1026 /// \param Method The Objective-C method against which this message
1027 /// send was type-checked. May be NULL.
1029 /// \param Args The message send arguments.
1031 /// \param RBracLoc The location of the closing square bracket ']'.
1032 static ObjCMessageExpr *Create(ASTContext &Context, QualType T,
1034 SourceLocation LBracLoc,
1035 SourceLocation SuperLoc,
1036 bool IsInstanceSuper,
1039 ArrayRef<SourceLocation> SelLocs,
1040 ObjCMethodDecl *Method,
1041 ArrayRef<Expr *> Args,
1042 SourceLocation RBracLoc,
1045 /// \brief Create a class message send.
1047 /// \param Context The ASTContext in which this expression will be created.
1049 /// \param T The result type of this message.
1051 /// \param VK The value kind of this message. A message returning
1052 /// a l-value or r-value reference will be an l-value or x-value,
1055 /// \param LBracLoc The location of the open square bracket '['.
1057 /// \param Receiver The type of the receiver, including
1058 /// source-location information.
1060 /// \param Sel The selector used to determine which method gets called.
1062 /// \param Method The Objective-C method against which this message
1063 /// send was type-checked. May be NULL.
1065 /// \param Args The message send arguments.
1067 /// \param RBracLoc The location of the closing square bracket ']'.
1068 static ObjCMessageExpr *Create(ASTContext &Context, QualType T,
1070 SourceLocation LBracLoc,
1071 TypeSourceInfo *Receiver,
1073 ArrayRef<SourceLocation> SelLocs,
1074 ObjCMethodDecl *Method,
1075 ArrayRef<Expr *> Args,
1076 SourceLocation RBracLoc,
1079 /// \brief Create an instance message send.
1081 /// \param Context The ASTContext in which this expression will be created.
1083 /// \param T The result type of this message.
1085 /// \param VK The value kind of this message. A message returning
1086 /// a l-value or r-value reference will be an l-value or x-value,
1089 /// \param LBracLoc The location of the open square bracket '['.
1091 /// \param Receiver The expression used to produce the object that
1092 /// will receive this message.
1094 /// \param Sel The selector used to determine which method gets called.
1096 /// \param Method The Objective-C method against which this message
1097 /// send was type-checked. May be NULL.
1099 /// \param Args The message send arguments.
1101 /// \param RBracLoc The location of the closing square bracket ']'.
1102 static ObjCMessageExpr *Create(ASTContext &Context, QualType T,
1104 SourceLocation LBracLoc,
1107 ArrayRef<SourceLocation> SeLocs,
1108 ObjCMethodDecl *Method,
1109 ArrayRef<Expr *> Args,
1110 SourceLocation RBracLoc,
1113 /// \brief Create an empty Objective-C message expression, to be
1114 /// filled in by subsequent calls.
1116 /// \param Context The context in which the message send will be created.
1118 /// \param NumArgs The number of message arguments, not including
1120 static ObjCMessageExpr *CreateEmpty(ASTContext &Context,
1122 unsigned NumStoredSelLocs);
1124 /// \brief Indicates whether the message send was implicitly
1125 /// generated by the implementation. If false, it was written explicitly
1126 /// in the source code.
1127 bool isImplicit() const { return IsImplicit; }
1129 /// \brief Determine the kind of receiver that this message is being
1131 ReceiverKind getReceiverKind() const { return (ReceiverKind)Kind; }
1133 /// \brief Source range of the receiver.
1134 SourceRange getReceiverRange() const;
1136 /// \brief Determine whether this is an instance message to either a
1137 /// computed object or to super.
1138 bool isInstanceMessage() const {
1139 return getReceiverKind() == Instance || getReceiverKind() == SuperInstance;
1142 /// \brief Determine whether this is an class message to either a
1143 /// specified class or to super.
1144 bool isClassMessage() const {
1145 return getReceiverKind() == Class || getReceiverKind() == SuperClass;
1148 /// \brief Returns the object expression (receiver) for an instance message,
1149 /// or null for a message that is not an instance message.
1150 Expr *getInstanceReceiver() {
1151 if (getReceiverKind() == Instance)
1152 return static_cast<Expr *>(getReceiverPointer());
1156 const Expr *getInstanceReceiver() const {
1157 return const_cast<ObjCMessageExpr*>(this)->getInstanceReceiver();
1160 /// \brief Turn this message send into an instance message that
1161 /// computes the receiver object with the given expression.
1162 void setInstanceReceiver(Expr *rec) {
1164 setReceiverPointer(rec);
1167 /// \brief Returns the type of a class message send, or NULL if the
1168 /// message is not a class message.
1169 QualType getClassReceiver() const {
1170 if (TypeSourceInfo *TSInfo = getClassReceiverTypeInfo())
1171 return TSInfo->getType();
1176 /// \brief Returns a type-source information of a class message
1177 /// send, or NULL if the message is not a class message.
1178 TypeSourceInfo *getClassReceiverTypeInfo() const {
1179 if (getReceiverKind() == Class)
1180 return reinterpret_cast<TypeSourceInfo *>(getReceiverPointer());
1184 void setClassReceiver(TypeSourceInfo *TSInfo) {
1186 setReceiverPointer(TSInfo);
1189 /// \brief Retrieve the location of the 'super' keyword for a class
1190 /// or instance message to 'super', otherwise an invalid source location.
1191 SourceLocation getSuperLoc() const {
1192 if (getReceiverKind() == SuperInstance || getReceiverKind() == SuperClass)
1195 return SourceLocation();
1198 /// \brief Retrieve the receiver type to which this message is being directed.
1200 /// This routine cross-cuts all of the different kinds of message
1201 /// sends to determine what the underlying (statically known) type
1202 /// of the receiver will be; use \c getReceiverKind() to determine
1203 /// whether the message is a class or an instance method, whether it
1204 /// is a send to super or not, etc.
1206 /// \returns The type of the receiver.
1207 QualType getReceiverType() const;
1209 /// \brief Retrieve the Objective-C interface to which this message
1210 /// is being directed, if known.
1212 /// This routine cross-cuts all of the different kinds of message
1213 /// sends to determine what the underlying (statically known) type
1214 /// of the receiver will be; use \c getReceiverKind() to determine
1215 /// whether the message is a class or an instance method, whether it
1216 /// is a send to super or not, etc.
1218 /// \returns The Objective-C interface if known, otherwise NULL.
1219 ObjCInterfaceDecl *getReceiverInterface() const;
1221 /// \brief Retrieve the type referred to by 'super'.
1223 /// The returned type will either be an ObjCInterfaceType (for an
1224 /// class message to super) or an ObjCObjectPointerType that refers
1225 /// to a class (for an instance message to super);
1226 QualType getSuperType() const {
1227 if (getReceiverKind() == SuperInstance || getReceiverKind() == SuperClass)
1228 return QualType::getFromOpaquePtr(getReceiverPointer());
1233 void setSuper(SourceLocation Loc, QualType T, bool IsInstanceSuper) {
1234 Kind = IsInstanceSuper? SuperInstance : SuperClass;
1236 setReceiverPointer(T.getAsOpaquePtr());
1239 Selector getSelector() const;
1241 void setSelector(Selector S) {
1243 SelectorOrMethod = reinterpret_cast<uintptr_t>(S.getAsOpaquePtr());
1246 const ObjCMethodDecl *getMethodDecl() const {
1248 return reinterpret_cast<const ObjCMethodDecl *>(SelectorOrMethod);
1253 ObjCMethodDecl *getMethodDecl() {
1255 return reinterpret_cast<ObjCMethodDecl *>(SelectorOrMethod);
1260 void setMethodDecl(ObjCMethodDecl *MD) {
1262 SelectorOrMethod = reinterpret_cast<uintptr_t>(MD);
1265 ObjCMethodFamily getMethodFamily() const {
1266 if (HasMethod) return getMethodDecl()->getMethodFamily();
1267 return getSelector().getMethodFamily();
1270 /// \brief Return the number of actual arguments in this message,
1271 /// not counting the receiver.
1272 unsigned getNumArgs() const { return NumArgs; }
1274 /// \brief Retrieve the arguments to this message, not including the
1277 return reinterpret_cast<Expr **>(this + 1) + 1;
1279 const Expr * const *getArgs() const {
1280 return reinterpret_cast<const Expr * const *>(this + 1) + 1;
1283 /// getArg - Return the specified argument.
1284 Expr *getArg(unsigned Arg) {
1285 assert(Arg < NumArgs && "Arg access out of range!");
1286 return cast<Expr>(getArgs()[Arg]);
1288 const Expr *getArg(unsigned Arg) const {
1289 assert(Arg < NumArgs && "Arg access out of range!");
1290 return cast<Expr>(getArgs()[Arg]);
1292 /// setArg - Set the specified argument.
1293 void setArg(unsigned Arg, Expr *ArgExpr) {
1294 assert(Arg < NumArgs && "Arg access out of range!");
1295 getArgs()[Arg] = ArgExpr;
1298 /// isDelegateInitCall - Answers whether this message send has been
1299 /// tagged as a "delegate init call", i.e. a call to a method in the
1300 /// -init family on self from within an -init method implementation.
1301 bool isDelegateInitCall() const { return IsDelegateInitCall; }
1302 void setDelegateInitCall(bool isDelegate) { IsDelegateInitCall = isDelegate; }
1304 SourceLocation getLeftLoc() const { return LBracLoc; }
1305 SourceLocation getRightLoc() const { return RBracLoc; }
1307 SourceLocation getSelectorStartLoc() const {
1309 return getLocStart();
1310 return getSelectorLoc(0);
1312 SourceLocation getSelectorLoc(unsigned Index) const {
1313 assert(Index < getNumSelectorLocs() && "Index out of range!");
1314 if (hasStandardSelLocs())
1315 return getStandardSelectorLoc(Index, getSelector(),
1316 getSelLocsKind() == SelLoc_StandardWithSpace,
1317 llvm::makeArrayRef(const_cast<Expr**>(getArgs()),
1320 return getStoredSelLocs()[Index];
1323 void getSelectorLocs(SmallVectorImpl<SourceLocation> &SelLocs) const;
1325 unsigned getNumSelectorLocs() const {
1328 Selector Sel = getSelector();
1329 if (Sel.isUnarySelector())
1331 return Sel.getNumArgs();
1334 void setSourceRange(SourceRange R) {
1335 LBracLoc = R.getBegin();
1336 RBracLoc = R.getEnd();
1338 SourceRange getSourceRange() const LLVM_READONLY {
1339 return SourceRange(LBracLoc, RBracLoc);
1342 static bool classof(const Stmt *T) {
1343 return T->getStmtClass() == ObjCMessageExprClass;
1347 child_range children();
1349 typedef ExprIterator arg_iterator;
1350 typedef ConstExprIterator const_arg_iterator;
1352 arg_iterator arg_begin() { return reinterpret_cast<Stmt **>(getArgs()); }
1353 arg_iterator arg_end() {
1354 return reinterpret_cast<Stmt **>(getArgs() + NumArgs);
1356 const_arg_iterator arg_begin() const {
1357 return reinterpret_cast<Stmt const * const*>(getArgs());
1359 const_arg_iterator arg_end() const {
1360 return reinterpret_cast<Stmt const * const*>(getArgs() + NumArgs);
1363 friend class ASTStmtReader;
1364 friend class ASTStmtWriter;
1367 /// ObjCIsaExpr - Represent X->isa and X.isa when X is an ObjC 'id' type.
1368 /// (similar in spirit to MemberExpr).
1369 class ObjCIsaExpr : public Expr {
1370 /// Base - the expression for the base object pointer.
1373 /// IsaMemberLoc - This is the location of the 'isa'.
1374 SourceLocation IsaMemberLoc;
1376 /// IsArrow - True if this is "X->F", false if this is "X.F".
1379 ObjCIsaExpr(Expr *base, bool isarrow, SourceLocation l, QualType ty)
1380 : Expr(ObjCIsaExprClass, ty, VK_LValue, OK_Ordinary,
1381 /*TypeDependent=*/false, base->isValueDependent(),
1382 base->isInstantiationDependent(),
1383 /*ContainsUnexpandedParameterPack=*/false),
1384 Base(base), IsaMemberLoc(l), IsArrow(isarrow) {}
1386 /// \brief Build an empty expression.
1387 explicit ObjCIsaExpr(EmptyShell Empty) : Expr(ObjCIsaExprClass, Empty) { }
1389 void setBase(Expr *E) { Base = E; }
1390 Expr *getBase() const { return cast<Expr>(Base); }
1392 bool isArrow() const { return IsArrow; }
1393 void setArrow(bool A) { IsArrow = A; }
1395 /// getMemberLoc - Return the location of the "member", in X->F, it is the
1396 /// location of 'F'.
1397 SourceLocation getIsaMemberLoc() const { return IsaMemberLoc; }
1398 void setIsaMemberLoc(SourceLocation L) { IsaMemberLoc = L; }
1400 SourceRange getSourceRange() const LLVM_READONLY {
1401 return SourceRange(getBase()->getLocStart(), IsaMemberLoc);
1404 SourceLocation getExprLoc() const LLVM_READONLY { return IsaMemberLoc; }
1406 static bool classof(const Stmt *T) {
1407 return T->getStmtClass() == ObjCIsaExprClass;
1411 child_range children() { return child_range(&Base, &Base+1); }
1415 /// ObjCIndirectCopyRestoreExpr - Represents the passing of a function
1416 /// argument by indirect copy-restore in ARC. This is used to support
1417 /// passing indirect arguments with the wrong lifetime, e.g. when
1418 /// passing the address of a __strong local variable to an 'out'
1419 /// parameter. This expression kind is only valid in an "argument"
1420 /// position to some sort of call expression.
1422 /// The parameter must have type 'pointer to T', and the argument must
1423 /// have type 'pointer to U', where T and U agree except possibly in
1424 /// qualification. If the argument value is null, then a null pointer
1425 /// is passed; otherwise it points to an object A, and:
1426 /// 1. A temporary object B of type T is initialized, either by
1427 /// zero-initialization (used when initializing an 'out' parameter)
1428 /// or copy-initialization (used when initializing an 'inout'
1430 /// 2. The address of the temporary is passed to the function.
1431 /// 3. If the call completes normally, A is move-assigned from B.
1432 /// 4. Finally, A is destroyed immediately.
1434 /// Currently 'T' must be a retainable object lifetime and must be
1435 /// __autoreleasing; this qualifier is ignored when initializing
1437 class ObjCIndirectCopyRestoreExpr : public Expr {
1440 // unsigned ObjCIndirectCopyRestoreBits.ShouldCopy : 1;
1442 friend class ASTReader;
1443 friend class ASTStmtReader;
1445 void setShouldCopy(bool shouldCopy) {
1446 ObjCIndirectCopyRestoreExprBits.ShouldCopy = shouldCopy;
1449 explicit ObjCIndirectCopyRestoreExpr(EmptyShell Empty)
1450 : Expr(ObjCIndirectCopyRestoreExprClass, Empty) { }
1453 ObjCIndirectCopyRestoreExpr(Expr *operand, QualType type, bool shouldCopy)
1454 : Expr(ObjCIndirectCopyRestoreExprClass, type, VK_LValue, OK_Ordinary,
1455 operand->isTypeDependent(), operand->isValueDependent(),
1456 operand->isInstantiationDependent(),
1457 operand->containsUnexpandedParameterPack()),
1459 setShouldCopy(shouldCopy);
1462 Expr *getSubExpr() { return cast<Expr>(Operand); }
1463 const Expr *getSubExpr() const { return cast<Expr>(Operand); }
1465 /// shouldCopy - True if we should do the 'copy' part of the
1466 /// copy-restore. If false, the temporary will be zero-initialized.
1467 bool shouldCopy() const { return ObjCIndirectCopyRestoreExprBits.ShouldCopy; }
1469 child_range children() { return child_range(&Operand, &Operand+1); }
1471 // Source locations are determined by the subexpression.
1472 SourceRange getSourceRange() const LLVM_READONLY {
1473 return Operand->getSourceRange();
1475 SourceLocation getExprLoc() const LLVM_READONLY {
1476 return getSubExpr()->getExprLoc();
1479 static bool classof(const Stmt *s) {
1480 return s->getStmtClass() == ObjCIndirectCopyRestoreExprClass;
1484 /// \brief An Objective-C "bridged" cast expression, which casts between
1485 /// Objective-C pointers and C pointers, transferring ownership in the process.
1488 /// NSString *str = (__bridge_transfer NSString *)CFCreateString();
1490 class ObjCBridgedCastExpr : public ExplicitCastExpr {
1491 SourceLocation LParenLoc;
1492 SourceLocation BridgeKeywordLoc;
1495 friend class ASTStmtReader;
1496 friend class ASTStmtWriter;
1499 ObjCBridgedCastExpr(SourceLocation LParenLoc, ObjCBridgeCastKind Kind,
1500 CastKind CK, SourceLocation BridgeKeywordLoc,
1501 TypeSourceInfo *TSInfo, Expr *Operand)
1502 : ExplicitCastExpr(ObjCBridgedCastExprClass, TSInfo->getType(), VK_RValue,
1503 CK, Operand, 0, TSInfo),
1504 LParenLoc(LParenLoc), BridgeKeywordLoc(BridgeKeywordLoc), Kind(Kind) { }
1506 /// \brief Construct an empty Objective-C bridged cast.
1507 explicit ObjCBridgedCastExpr(EmptyShell Shell)
1508 : ExplicitCastExpr(ObjCBridgedCastExprClass, Shell, 0) { }
1510 SourceLocation getLParenLoc() const { return LParenLoc; }
1512 /// \brief Determine which kind of bridge is being performed via this cast.
1513 ObjCBridgeCastKind getBridgeKind() const {
1514 return static_cast<ObjCBridgeCastKind>(Kind);
1517 /// \brief Retrieve the kind of bridge being performed as a string.
1518 StringRef getBridgeKindName() const;
1520 /// \brief The location of the bridge keyword.
1521 SourceLocation getBridgeKeywordLoc() const { return BridgeKeywordLoc; }
1523 SourceRange getSourceRange() const LLVM_READONLY {
1524 return SourceRange(LParenLoc, getSubExpr()->getLocEnd());
1527 static bool classof(const Stmt *T) {
1528 return T->getStmtClass() == ObjCBridgedCastExprClass;
1532 } // end namespace clang