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/Decl.h"
18 #include "clang/AST/DeclObjC.h"
19 #include "clang/AST/Expr.h"
20 #include "clang/AST/OperationKinds.h"
21 #include "clang/AST/SelectorLocationsKind.h"
22 #include "clang/AST/Stmt.h"
23 #include "clang/AST/Type.h"
24 #include "clang/Basic/IdentifierTable.h"
25 #include "clang/Basic/LLVM.h"
26 #include "clang/Basic/SourceLocation.h"
27 #include "clang/Basic/Specifiers.h"
28 #include "llvm/ADT/ArrayRef.h"
29 #include "llvm/ADT/None.h"
30 #include "llvm/ADT/Optional.h"
31 #include "llvm/ADT/PointerIntPair.h"
32 #include "llvm/ADT/PointerUnion.h"
33 #include "llvm/ADT/StringRef.h"
34 #include "llvm/ADT/iterator_range.h"
35 #include "llvm/Support/Casting.h"
36 #include "llvm/Support/Compiler.h"
37 #include "llvm/Support/TrailingObjects.h"
38 #include "llvm/Support/VersionTuple.h"
39 #include "llvm/Support/type_traits.h"
47 class CXXBaseSpecifier;
49 /// ObjCStringLiteral, used for Objective-C string literals
51 class ObjCStringLiteral : public Expr {
56 ObjCStringLiteral(StringLiteral *SL, QualType T, SourceLocation L)
57 : Expr(ObjCStringLiteralClass, T, VK_RValue, OK_Ordinary, false, false,
59 String(SL), AtLoc(L) {}
60 explicit ObjCStringLiteral(EmptyShell Empty)
61 : Expr(ObjCStringLiteralClass, Empty) {}
63 StringLiteral *getString() { return cast<StringLiteral>(String); }
64 const StringLiteral *getString() const { return cast<StringLiteral>(String); }
65 void setString(StringLiteral *S) { String = S; }
67 SourceLocation getAtLoc() const { return AtLoc; }
68 void setAtLoc(SourceLocation L) { AtLoc = L; }
70 SourceLocation getLocStart() const LLVM_READONLY { return getBeginLoc(); }
71 SourceLocation getBeginLoc() const LLVM_READONLY { return AtLoc; }
72 SourceLocation getLocEnd() const LLVM_READONLY { return getEndLoc(); }
73 SourceLocation getEndLoc() const LLVM_READONLY { return String->getLocEnd(); }
76 child_range children() { return child_range(&String, &String+1); }
78 static bool classof(const Stmt *T) {
79 return T->getStmtClass() == ObjCStringLiteralClass;
83 /// ObjCBoolLiteralExpr - Objective-C Boolean Literal.
84 class ObjCBoolLiteralExpr : public Expr {
89 ObjCBoolLiteralExpr(bool val, QualType Ty, SourceLocation l)
90 : Expr(ObjCBoolLiteralExprClass, Ty, VK_RValue, OK_Ordinary, false, false,
93 explicit ObjCBoolLiteralExpr(EmptyShell Empty)
94 : Expr(ObjCBoolLiteralExprClass, Empty) {}
96 bool getValue() const { return Value; }
97 void setValue(bool V) { Value = V; }
99 SourceLocation getLocStart() const LLVM_READONLY { return getBeginLoc(); }
100 SourceLocation getBeginLoc() const LLVM_READONLY { return Loc; }
101 SourceLocation getLocEnd() const LLVM_READONLY { return getEndLoc(); }
102 SourceLocation getEndLoc() const LLVM_READONLY { return Loc; }
104 SourceLocation getLocation() const { return Loc; }
105 void setLocation(SourceLocation L) { Loc = L; }
108 child_range children() {
109 return child_range(child_iterator(), child_iterator());
112 static bool classof(const Stmt *T) {
113 return T->getStmtClass() == ObjCBoolLiteralExprClass;
117 /// ObjCBoxedExpr - used for generalized expression boxing.
118 /// as in: @(strdup("hello world")), @(random()) or @(view.frame)
119 /// Also used for boxing non-parenthesized numeric literals;
120 /// as in: @42 or \@true (c++/objc++) or \@__objc_yes (c/objc).
121 class ObjCBoxedExpr : public Expr {
123 ObjCMethodDecl *BoxingMethod;
127 friend class ASTStmtReader;
129 ObjCBoxedExpr(Expr *E, QualType T, ObjCMethodDecl *method,
131 : Expr(ObjCBoxedExprClass, T, VK_RValue, OK_Ordinary,
132 E->isTypeDependent(), E->isValueDependent(),
133 E->isInstantiationDependent(),
134 E->containsUnexpandedParameterPack()),
135 SubExpr(E), BoxingMethod(method), Range(R) {}
136 explicit ObjCBoxedExpr(EmptyShell Empty)
137 : Expr(ObjCBoxedExprClass, Empty) {}
139 Expr *getSubExpr() { return cast<Expr>(SubExpr); }
140 const Expr *getSubExpr() const { return cast<Expr>(SubExpr); }
142 ObjCMethodDecl *getBoxingMethod() const {
146 SourceLocation getAtLoc() const { return Range.getBegin(); }
148 SourceLocation getLocStart() const LLVM_READONLY { return getBeginLoc(); }
149 SourceLocation getBeginLoc() const LLVM_READONLY { return Range.getBegin(); }
150 SourceLocation getLocEnd() const LLVM_READONLY { return getEndLoc(); }
151 SourceLocation getEndLoc() const LLVM_READONLY { return Range.getEnd(); }
153 SourceRange getSourceRange() const LLVM_READONLY {
158 child_range children() { return child_range(&SubExpr, &SubExpr+1); }
160 using const_arg_iterator = ConstExprIterator;
162 const_arg_iterator arg_begin() const {
163 return reinterpret_cast<Stmt const * const*>(&SubExpr);
166 const_arg_iterator arg_end() const {
167 return reinterpret_cast<Stmt const * const*>(&SubExpr + 1);
170 static bool classof(const Stmt *T) {
171 return T->getStmtClass() == ObjCBoxedExprClass;
175 /// ObjCArrayLiteral - used for objective-c array containers; as in:
176 /// @[@"Hello", NSApp, [NSNumber numberWithInt:42]];
177 class ObjCArrayLiteral final
179 private llvm::TrailingObjects<ObjCArrayLiteral, Expr *> {
180 unsigned NumElements;
182 ObjCMethodDecl *ArrayWithObjectsMethod;
184 ObjCArrayLiteral(ArrayRef<Expr *> Elements,
185 QualType T, ObjCMethodDecl * Method,
188 explicit ObjCArrayLiteral(EmptyShell Empty, unsigned NumElements)
189 : Expr(ObjCArrayLiteralClass, Empty), NumElements(NumElements) {}
192 friend class ASTStmtReader;
193 friend TrailingObjects;
195 static ObjCArrayLiteral *Create(const ASTContext &C,
196 ArrayRef<Expr *> Elements,
197 QualType T, ObjCMethodDecl * Method,
200 static ObjCArrayLiteral *CreateEmpty(const ASTContext &C,
201 unsigned NumElements);
203 SourceLocation getLocStart() const LLVM_READONLY { return getBeginLoc(); }
204 SourceLocation getBeginLoc() const LLVM_READONLY { return Range.getBegin(); }
205 SourceLocation getLocEnd() const LLVM_READONLY { return getEndLoc(); }
206 SourceLocation getEndLoc() const LLVM_READONLY { return Range.getEnd(); }
207 SourceRange getSourceRange() const LLVM_READONLY { return Range; }
209 /// Retrieve elements of array of literals.
210 Expr **getElements() { return getTrailingObjects<Expr *>(); }
212 /// Retrieve elements of array of literals.
213 const Expr * const *getElements() const {
214 return getTrailingObjects<Expr *>();
217 /// getNumElements - Return number of elements of objective-c array literal.
218 unsigned getNumElements() const { return NumElements; }
220 /// getElement - Return the Element at the specified index.
221 Expr *getElement(unsigned Index) {
222 assert((Index < NumElements) && "Arg access out of range!");
223 return getElements()[Index];
225 const Expr *getElement(unsigned Index) const {
226 assert((Index < NumElements) && "Arg access out of range!");
227 return getElements()[Index];
230 ObjCMethodDecl *getArrayWithObjectsMethod() const {
231 return ArrayWithObjectsMethod;
235 child_range children() {
236 return child_range(reinterpret_cast<Stmt **>(getElements()),
237 reinterpret_cast<Stmt **>(getElements()) + NumElements);
240 static bool classof(const Stmt *T) {
241 return T->getStmtClass() == ObjCArrayLiteralClass;
245 /// An element in an Objective-C dictionary literal.
247 struct ObjCDictionaryElement {
248 /// The key for the dictionary element.
251 /// The value of the dictionary element.
254 /// The location of the ellipsis, if this is a pack expansion.
255 SourceLocation EllipsisLoc;
257 /// The number of elements this pack expansion will expand to, if
258 /// this is a pack expansion and is known.
259 Optional<unsigned> NumExpansions;
261 /// Determines whether this dictionary element is a pack expansion.
262 bool isPackExpansion() const { return EllipsisLoc.isValid(); }
269 template <> struct isPodLike<clang::ObjCDictionaryElement> : std::true_type {};
275 /// Internal struct for storing Key/value pair.
276 struct ObjCDictionaryLiteral_KeyValuePair {
281 /// Internal struct to describes an element that is a pack
282 /// expansion, used if any of the elements in the dictionary literal
283 /// are pack expansions.
284 struct ObjCDictionaryLiteral_ExpansionData {
285 /// The location of the ellipsis, if this element is a pack
287 SourceLocation EllipsisLoc;
289 /// If non-zero, the number of elements that this pack
290 /// expansion will expand to (+1).
291 unsigned NumExpansionsPlusOne;
294 /// ObjCDictionaryLiteral - AST node to represent objective-c dictionary
295 /// literals; as in: @{@"name" : NSUserName(), @"date" : [NSDate date] };
296 class ObjCDictionaryLiteral final
298 private llvm::TrailingObjects<ObjCDictionaryLiteral,
299 ObjCDictionaryLiteral_KeyValuePair,
300 ObjCDictionaryLiteral_ExpansionData> {
301 /// The number of elements in this dictionary literal.
302 unsigned NumElements : 31;
304 /// Determine whether this dictionary literal has any pack expansions.
306 /// If the dictionary literal has pack expansions, then there will
307 /// be an array of pack expansion data following the array of
308 /// key/value pairs, which provide the locations of the ellipses (if
309 /// any) and number of elements in the expansion (if known). If
310 /// there are no pack expansions, we optimize away this storage.
311 unsigned HasPackExpansions : 1;
314 ObjCMethodDecl *DictWithObjectsMethod;
316 using KeyValuePair = ObjCDictionaryLiteral_KeyValuePair;
317 using ExpansionData = ObjCDictionaryLiteral_ExpansionData;
319 ObjCDictionaryLiteral(ArrayRef<ObjCDictionaryElement> VK,
320 bool HasPackExpansions,
321 QualType T, ObjCMethodDecl *method,
324 explicit ObjCDictionaryLiteral(EmptyShell Empty, unsigned NumElements,
325 bool HasPackExpansions)
326 : Expr(ObjCDictionaryLiteralClass, Empty), NumElements(NumElements),
327 HasPackExpansions(HasPackExpansions) {}
329 size_t numTrailingObjects(OverloadToken<KeyValuePair>) const {
334 friend class ASTStmtReader;
335 friend class ASTStmtWriter;
336 friend TrailingObjects;
338 static ObjCDictionaryLiteral *Create(const ASTContext &C,
339 ArrayRef<ObjCDictionaryElement> VK,
340 bool HasPackExpansions,
341 QualType T, ObjCMethodDecl *method,
344 static ObjCDictionaryLiteral *CreateEmpty(const ASTContext &C,
345 unsigned NumElements,
346 bool HasPackExpansions);
348 /// getNumElements - Return number of elements of objective-c dictionary
350 unsigned getNumElements() const { return NumElements; }
352 ObjCDictionaryElement getKeyValueElement(unsigned Index) const {
353 assert((Index < NumElements) && "Arg access out of range!");
354 const KeyValuePair &KV = getTrailingObjects<KeyValuePair>()[Index];
355 ObjCDictionaryElement Result = { KV.Key, KV.Value, SourceLocation(), None };
356 if (HasPackExpansions) {
357 const ExpansionData &Expansion =
358 getTrailingObjects<ExpansionData>()[Index];
359 Result.EllipsisLoc = Expansion.EllipsisLoc;
360 if (Expansion.NumExpansionsPlusOne > 0)
361 Result.NumExpansions = Expansion.NumExpansionsPlusOne - 1;
366 ObjCMethodDecl *getDictWithObjectsMethod() const {
367 return DictWithObjectsMethod;
370 SourceLocation getLocStart() const LLVM_READONLY { return getBeginLoc(); }
371 SourceLocation getBeginLoc() const LLVM_READONLY { return Range.getBegin(); }
372 SourceLocation getLocEnd() const LLVM_READONLY { return getEndLoc(); }
373 SourceLocation getEndLoc() const LLVM_READONLY { return Range.getEnd(); }
374 SourceRange getSourceRange() const LLVM_READONLY { return Range; }
377 child_range children() {
378 // Note: we're taking advantage of the layout of the KeyValuePair struct
379 // here. If that struct changes, this code will need to change as well.
380 static_assert(sizeof(KeyValuePair) == sizeof(Stmt *) * 2,
381 "KeyValuePair is expected size");
383 reinterpret_cast<Stmt **>(getTrailingObjects<KeyValuePair>()),
384 reinterpret_cast<Stmt **>(getTrailingObjects<KeyValuePair>()) +
388 static bool classof(const Stmt *T) {
389 return T->getStmtClass() == ObjCDictionaryLiteralClass;
393 /// ObjCEncodeExpr, used for \@encode in Objective-C. \@encode has the same
394 /// type and behavior as StringLiteral except that the string initializer is
395 /// obtained from ASTContext with the encoding type as an argument.
396 class ObjCEncodeExpr : public Expr {
397 TypeSourceInfo *EncodedType;
398 SourceLocation AtLoc, RParenLoc;
401 ObjCEncodeExpr(QualType T, TypeSourceInfo *EncodedType,
402 SourceLocation at, SourceLocation rp)
403 : Expr(ObjCEncodeExprClass, T, VK_LValue, OK_Ordinary,
404 EncodedType->getType()->isDependentType(),
405 EncodedType->getType()->isDependentType(),
406 EncodedType->getType()->isInstantiationDependentType(),
407 EncodedType->getType()->containsUnexpandedParameterPack()),
408 EncodedType(EncodedType), AtLoc(at), RParenLoc(rp) {}
410 explicit ObjCEncodeExpr(EmptyShell Empty) : Expr(ObjCEncodeExprClass, Empty){}
412 SourceLocation getAtLoc() const { return AtLoc; }
413 void setAtLoc(SourceLocation L) { AtLoc = L; }
414 SourceLocation getRParenLoc() const { return RParenLoc; }
415 void setRParenLoc(SourceLocation L) { RParenLoc = L; }
417 QualType getEncodedType() const { return EncodedType->getType(); }
419 TypeSourceInfo *getEncodedTypeSourceInfo() const { return EncodedType; }
421 void setEncodedTypeSourceInfo(TypeSourceInfo *EncType) {
422 EncodedType = EncType;
425 SourceLocation getLocStart() const LLVM_READONLY { return getBeginLoc(); }
426 SourceLocation getBeginLoc() const LLVM_READONLY { return AtLoc; }
427 SourceLocation getLocEnd() const LLVM_READONLY { return getEndLoc(); }
428 SourceLocation getEndLoc() const LLVM_READONLY { return RParenLoc; }
431 child_range children() {
432 return child_range(child_iterator(), child_iterator());
435 static bool classof(const Stmt *T) {
436 return T->getStmtClass() == ObjCEncodeExprClass;
440 /// ObjCSelectorExpr used for \@selector in Objective-C.
441 class ObjCSelectorExpr : public Expr {
443 SourceLocation AtLoc, RParenLoc;
446 ObjCSelectorExpr(QualType T, Selector selInfo,
447 SourceLocation at, SourceLocation rp)
448 : Expr(ObjCSelectorExprClass, T, VK_RValue, OK_Ordinary, false, false,
450 SelName(selInfo), AtLoc(at), RParenLoc(rp) {}
451 explicit ObjCSelectorExpr(EmptyShell Empty)
452 : Expr(ObjCSelectorExprClass, Empty) {}
454 Selector getSelector() const { return SelName; }
455 void setSelector(Selector S) { SelName = S; }
457 SourceLocation getAtLoc() const { return AtLoc; }
458 SourceLocation getRParenLoc() const { return RParenLoc; }
459 void setAtLoc(SourceLocation L) { AtLoc = L; }
460 void setRParenLoc(SourceLocation L) { RParenLoc = L; }
462 SourceLocation getLocStart() const LLVM_READONLY { return getBeginLoc(); }
463 SourceLocation getBeginLoc() const LLVM_READONLY { return AtLoc; }
464 SourceLocation getLocEnd() const LLVM_READONLY { return getEndLoc(); }
465 SourceLocation getEndLoc() const LLVM_READONLY { return RParenLoc; }
467 /// getNumArgs - Return the number of actual arguments to this call.
468 unsigned getNumArgs() const { return SelName.getNumArgs(); }
471 child_range children() {
472 return child_range(child_iterator(), child_iterator());
475 static bool classof(const Stmt *T) {
476 return T->getStmtClass() == ObjCSelectorExprClass;
480 /// ObjCProtocolExpr used for protocol expression in Objective-C.
482 /// This is used as: \@protocol(foo), as in:
484 /// [obj conformsToProtocol:@protocol(foo)]
487 /// The return type is "Protocol*".
488 class ObjCProtocolExpr : public Expr {
489 ObjCProtocolDecl *TheProtocol;
490 SourceLocation AtLoc, ProtoLoc, RParenLoc;
493 friend class ASTStmtReader;
494 friend class ASTStmtWriter;
496 ObjCProtocolExpr(QualType T, ObjCProtocolDecl *protocol,
497 SourceLocation at, SourceLocation protoLoc, SourceLocation rp)
498 : Expr(ObjCProtocolExprClass, T, VK_RValue, OK_Ordinary, false, false,
500 TheProtocol(protocol), AtLoc(at), ProtoLoc(protoLoc), RParenLoc(rp) {}
501 explicit ObjCProtocolExpr(EmptyShell Empty)
502 : Expr(ObjCProtocolExprClass, Empty) {}
504 ObjCProtocolDecl *getProtocol() const { return TheProtocol; }
505 void setProtocol(ObjCProtocolDecl *P) { TheProtocol = P; }
507 SourceLocation getProtocolIdLoc() const { return ProtoLoc; }
508 SourceLocation getAtLoc() const { return AtLoc; }
509 SourceLocation getRParenLoc() const { return RParenLoc; }
510 void setAtLoc(SourceLocation L) { AtLoc = L; }
511 void setRParenLoc(SourceLocation L) { RParenLoc = L; }
513 SourceLocation getLocStart() const LLVM_READONLY { return getBeginLoc(); }
514 SourceLocation getBeginLoc() const LLVM_READONLY { return AtLoc; }
515 SourceLocation getLocEnd() const LLVM_READONLY { return getEndLoc(); }
516 SourceLocation getEndLoc() const LLVM_READONLY { return RParenLoc; }
519 child_range children() {
520 return child_range(child_iterator(), child_iterator());
523 static bool classof(const Stmt *T) {
524 return T->getStmtClass() == ObjCProtocolExprClass;
528 /// ObjCIvarRefExpr - A reference to an ObjC instance variable.
529 class ObjCIvarRefExpr : public Expr {
534 /// OpLoc - This is the location of '.' or '->'
535 SourceLocation OpLoc;
537 // True if this is "X->F", false if this is "X.F".
540 // True if ivar reference has no base (self assumed).
544 ObjCIvarRefExpr(ObjCIvarDecl *d, QualType t,
545 SourceLocation l, SourceLocation oploc,
547 bool arrow = false, bool freeIvar = false)
548 : Expr(ObjCIvarRefExprClass, t, VK_LValue,
549 d->isBitField() ? OK_BitField : OK_Ordinary,
550 /*TypeDependent=*/false, base->isValueDependent(),
551 base->isInstantiationDependent(),
552 base->containsUnexpandedParameterPack()),
553 D(d), Base(base), Loc(l), OpLoc(oploc), IsArrow(arrow),
554 IsFreeIvar(freeIvar) {}
556 explicit ObjCIvarRefExpr(EmptyShell Empty)
557 : Expr(ObjCIvarRefExprClass, Empty) {}
559 ObjCIvarDecl *getDecl() { return D; }
560 const ObjCIvarDecl *getDecl() const { return D; }
561 void setDecl(ObjCIvarDecl *d) { D = d; }
563 const Expr *getBase() const { return cast<Expr>(Base); }
564 Expr *getBase() { return cast<Expr>(Base); }
565 void setBase(Expr * base) { Base = base; }
567 bool isArrow() const { return IsArrow; }
568 bool isFreeIvar() const { return IsFreeIvar; }
569 void setIsArrow(bool A) { IsArrow = A; }
570 void setIsFreeIvar(bool A) { IsFreeIvar = A; }
572 SourceLocation getLocation() const { return Loc; }
573 void setLocation(SourceLocation L) { Loc = L; }
575 SourceLocation getLocStart() const LLVM_READONLY { return getBeginLoc(); }
576 SourceLocation getBeginLoc() const LLVM_READONLY {
577 return isFreeIvar() ? Loc : getBase()->getLocStart();
579 SourceLocation getLocEnd() const LLVM_READONLY { return getEndLoc(); }
580 SourceLocation getEndLoc() const LLVM_READONLY { return Loc; }
582 SourceLocation getOpLoc() const { return OpLoc; }
583 void setOpLoc(SourceLocation L) { OpLoc = L; }
586 child_range children() { return child_range(&Base, &Base+1); }
588 static bool classof(const Stmt *T) {
589 return T->getStmtClass() == ObjCIvarRefExprClass;
593 /// ObjCPropertyRefExpr - A dot-syntax expression to access an ObjC
595 class ObjCPropertyRefExpr : public Expr {
597 /// If the bool is true, this is an implicit property reference; the
598 /// pointer is an (optional) ObjCMethodDecl and Setter may be set.
599 /// if the bool is false, this is an explicit property reference;
600 /// the pointer is an ObjCPropertyDecl and Setter is always null.
601 llvm::PointerIntPair<NamedDecl *, 1, bool> PropertyOrGetter;
603 /// Indicates whether the property reference will result in a message
604 /// to the getter, the setter, or both.
605 /// This applies to both implicit and explicit property references.
606 enum MethodRefFlags {
608 MethodRef_Getter = 0x1,
609 MethodRef_Setter = 0x2
612 /// Contains the Setter method pointer and MethodRefFlags bit flags.
613 llvm::PointerIntPair<ObjCMethodDecl *, 2, unsigned> SetterAndMethodRefFlags;
615 // FIXME: Maybe we should store the property identifier here,
616 // because it's not rederivable from the other data when there's an
617 // implicit property with no getter (because the 'foo' -> 'setFoo:'
618 // transformation is lossy on the first character).
620 SourceLocation IdLoc;
622 /// When the receiver in property access is 'super', this is
623 /// the location of the 'super' keyword. When it's an interface,
624 /// this is that interface.
625 SourceLocation ReceiverLoc;
626 llvm::PointerUnion3<Stmt *, const Type *, ObjCInterfaceDecl *> Receiver;
629 ObjCPropertyRefExpr(ObjCPropertyDecl *PD, QualType t,
630 ExprValueKind VK, ExprObjectKind OK,
631 SourceLocation l, Expr *base)
632 : Expr(ObjCPropertyRefExprClass, t, VK, OK,
633 /*TypeDependent=*/false, base->isValueDependent(),
634 base->isInstantiationDependent(),
635 base->containsUnexpandedParameterPack()),
636 PropertyOrGetter(PD, false), IdLoc(l), Receiver(base) {
637 assert(t->isSpecificPlaceholderType(BuiltinType::PseudoObject));
640 ObjCPropertyRefExpr(ObjCPropertyDecl *PD, QualType t,
641 ExprValueKind VK, ExprObjectKind OK,
642 SourceLocation l, SourceLocation sl, QualType st)
643 : Expr(ObjCPropertyRefExprClass, t, VK, OK,
644 /*TypeDependent=*/false, false, st->isInstantiationDependentType(),
645 st->containsUnexpandedParameterPack()),
646 PropertyOrGetter(PD, false), IdLoc(l), ReceiverLoc(sl),
647 Receiver(st.getTypePtr()) {
648 assert(t->isSpecificPlaceholderType(BuiltinType::PseudoObject));
651 ObjCPropertyRefExpr(ObjCMethodDecl *Getter, ObjCMethodDecl *Setter,
652 QualType T, ExprValueKind VK, ExprObjectKind OK,
653 SourceLocation IdLoc, Expr *Base)
654 : Expr(ObjCPropertyRefExprClass, T, VK, OK, false,
655 Base->isValueDependent(), Base->isInstantiationDependent(),
656 Base->containsUnexpandedParameterPack()),
657 PropertyOrGetter(Getter, true), SetterAndMethodRefFlags(Setter, 0),
658 IdLoc(IdLoc), Receiver(Base) {
659 assert(T->isSpecificPlaceholderType(BuiltinType::PseudoObject));
662 ObjCPropertyRefExpr(ObjCMethodDecl *Getter, ObjCMethodDecl *Setter,
663 QualType T, ExprValueKind VK, ExprObjectKind OK,
664 SourceLocation IdLoc,
665 SourceLocation SuperLoc, QualType SuperTy)
666 : Expr(ObjCPropertyRefExprClass, T, VK, OK, false, false, false, false),
667 PropertyOrGetter(Getter, true), SetterAndMethodRefFlags(Setter, 0),
668 IdLoc(IdLoc), ReceiverLoc(SuperLoc), Receiver(SuperTy.getTypePtr()) {
669 assert(T->isSpecificPlaceholderType(BuiltinType::PseudoObject));
672 ObjCPropertyRefExpr(ObjCMethodDecl *Getter, ObjCMethodDecl *Setter,
673 QualType T, ExprValueKind VK, ExprObjectKind OK,
674 SourceLocation IdLoc,
675 SourceLocation ReceiverLoc, ObjCInterfaceDecl *Receiver)
676 : Expr(ObjCPropertyRefExprClass, T, VK, OK, false, false, false, false),
677 PropertyOrGetter(Getter, true), SetterAndMethodRefFlags(Setter, 0),
678 IdLoc(IdLoc), ReceiverLoc(ReceiverLoc), Receiver(Receiver) {
679 assert(T->isSpecificPlaceholderType(BuiltinType::PseudoObject));
682 explicit ObjCPropertyRefExpr(EmptyShell Empty)
683 : Expr(ObjCPropertyRefExprClass, Empty) {}
685 bool isImplicitProperty() const { return PropertyOrGetter.getInt(); }
686 bool isExplicitProperty() const { return !PropertyOrGetter.getInt(); }
688 ObjCPropertyDecl *getExplicitProperty() const {
689 assert(!isImplicitProperty());
690 return cast<ObjCPropertyDecl>(PropertyOrGetter.getPointer());
693 ObjCMethodDecl *getImplicitPropertyGetter() const {
694 assert(isImplicitProperty());
695 return cast_or_null<ObjCMethodDecl>(PropertyOrGetter.getPointer());
698 ObjCMethodDecl *getImplicitPropertySetter() const {
699 assert(isImplicitProperty());
700 return SetterAndMethodRefFlags.getPointer();
703 Selector getGetterSelector() const {
704 if (isImplicitProperty())
705 return getImplicitPropertyGetter()->getSelector();
706 return getExplicitProperty()->getGetterName();
709 Selector getSetterSelector() const {
710 if (isImplicitProperty())
711 return getImplicitPropertySetter()->getSelector();
712 return getExplicitProperty()->getSetterName();
715 /// True if the property reference will result in a message to the
717 /// This applies to both implicit and explicit property references.
718 bool isMessagingGetter() const {
719 return SetterAndMethodRefFlags.getInt() & MethodRef_Getter;
722 /// True if the property reference will result in a message to the
724 /// This applies to both implicit and explicit property references.
725 bool isMessagingSetter() const {
726 return SetterAndMethodRefFlags.getInt() & MethodRef_Setter;
729 void setIsMessagingGetter(bool val = true) {
730 setMethodRefFlag(MethodRef_Getter, val);
733 void setIsMessagingSetter(bool val = true) {
734 setMethodRefFlag(MethodRef_Setter, val);
737 const Expr *getBase() const {
738 return cast<Expr>(Receiver.get<Stmt*>());
741 return cast<Expr>(Receiver.get<Stmt*>());
744 SourceLocation getLocation() const { return IdLoc; }
746 SourceLocation getReceiverLocation() const { return ReceiverLoc; }
748 QualType getSuperReceiverType() const {
749 return QualType(Receiver.get<const Type*>(), 0);
752 ObjCInterfaceDecl *getClassReceiver() const {
753 return Receiver.get<ObjCInterfaceDecl*>();
756 bool isObjectReceiver() const { return Receiver.is<Stmt*>(); }
757 bool isSuperReceiver() const { return Receiver.is<const Type*>(); }
758 bool isClassReceiver() const { return Receiver.is<ObjCInterfaceDecl*>(); }
760 /// Determine the type of the base, regardless of the kind of receiver.
761 QualType getReceiverType(const ASTContext &ctx) const;
763 SourceLocation getLocStart() const LLVM_READONLY { return getBeginLoc(); }
764 SourceLocation getBeginLoc() const LLVM_READONLY {
765 return isObjectReceiver() ? getBase()->getLocStart() :getReceiverLocation();
768 SourceLocation getLocEnd() const LLVM_READONLY { return getEndLoc(); }
769 SourceLocation getEndLoc() const LLVM_READONLY { return IdLoc; }
772 child_range children() {
773 if (Receiver.is<Stmt*>()) {
774 Stmt **begin = reinterpret_cast<Stmt**>(&Receiver); // hack!
775 return child_range(begin, begin+1);
777 return child_range(child_iterator(), child_iterator());
780 static bool classof(const Stmt *T) {
781 return T->getStmtClass() == ObjCPropertyRefExprClass;
785 friend class ASTStmtReader;
786 friend class ASTStmtWriter;
788 void setExplicitProperty(ObjCPropertyDecl *D, unsigned methRefFlags) {
789 PropertyOrGetter.setPointer(D);
790 PropertyOrGetter.setInt(false);
791 SetterAndMethodRefFlags.setPointer(nullptr);
792 SetterAndMethodRefFlags.setInt(methRefFlags);
795 void setImplicitProperty(ObjCMethodDecl *Getter, ObjCMethodDecl *Setter,
796 unsigned methRefFlags) {
797 PropertyOrGetter.setPointer(Getter);
798 PropertyOrGetter.setInt(true);
799 SetterAndMethodRefFlags.setPointer(Setter);
800 SetterAndMethodRefFlags.setInt(methRefFlags);
803 void setBase(Expr *Base) { Receiver = Base; }
804 void setSuperReceiver(QualType T) { Receiver = T.getTypePtr(); }
805 void setClassReceiver(ObjCInterfaceDecl *D) { Receiver = D; }
807 void setLocation(SourceLocation L) { IdLoc = L; }
808 void setReceiverLocation(SourceLocation Loc) { ReceiverLoc = Loc; }
810 void setMethodRefFlag(MethodRefFlags flag, bool val) {
811 unsigned f = SetterAndMethodRefFlags.getInt();
816 SetterAndMethodRefFlags.setInt(f);
820 /// ObjCSubscriptRefExpr - used for array and dictionary subscripting.
821 /// array[4] = array[3]; dictionary[key] = dictionary[alt_key];
822 class ObjCSubscriptRefExpr : public Expr {
823 // Location of ']' in an indexing expression.
824 SourceLocation RBracket;
826 // array/dictionary base expression.
827 // for arrays, this is a numeric expression. For dictionaries, this is
828 // an objective-c object pointer expression.
829 enum { BASE, KEY, END_EXPR };
830 Stmt* SubExprs[END_EXPR];
832 ObjCMethodDecl *GetAtIndexMethodDecl;
834 // For immutable objects this is null. When ObjCSubscriptRefExpr is to read
835 // an indexed object this is null too.
836 ObjCMethodDecl *SetAtIndexMethodDecl;
839 ObjCSubscriptRefExpr(Expr *base, Expr *key, QualType T,
840 ExprValueKind VK, ExprObjectKind OK,
841 ObjCMethodDecl *getMethod,
842 ObjCMethodDecl *setMethod, SourceLocation RB)
843 : Expr(ObjCSubscriptRefExprClass, T, VK, OK,
844 base->isTypeDependent() || key->isTypeDependent(),
845 base->isValueDependent() || key->isValueDependent(),
846 (base->isInstantiationDependent() ||
847 key->isInstantiationDependent()),
848 (base->containsUnexpandedParameterPack() ||
849 key->containsUnexpandedParameterPack())),
850 RBracket(RB), GetAtIndexMethodDecl(getMethod),
851 SetAtIndexMethodDecl(setMethod) {
852 SubExprs[BASE] = base; SubExprs[KEY] = key;
855 explicit ObjCSubscriptRefExpr(EmptyShell Empty)
856 : Expr(ObjCSubscriptRefExprClass, Empty) {}
858 SourceLocation getRBracket() const { return RBracket; }
859 void setRBracket(SourceLocation RB) { RBracket = RB; }
861 SourceLocation getLocStart() const LLVM_READONLY { return getBeginLoc(); }
862 SourceLocation getBeginLoc() const LLVM_READONLY {
863 return SubExprs[BASE]->getLocStart();
866 SourceLocation getLocEnd() const LLVM_READONLY { return getEndLoc(); }
867 SourceLocation getEndLoc() const LLVM_READONLY { return RBracket; }
869 Expr *getBaseExpr() const { return cast<Expr>(SubExprs[BASE]); }
870 void setBaseExpr(Stmt *S) { SubExprs[BASE] = S; }
872 Expr *getKeyExpr() const { return cast<Expr>(SubExprs[KEY]); }
873 void setKeyExpr(Stmt *S) { SubExprs[KEY] = S; }
875 ObjCMethodDecl *getAtIndexMethodDecl() const {
876 return GetAtIndexMethodDecl;
879 ObjCMethodDecl *setAtIndexMethodDecl() const {
880 return SetAtIndexMethodDecl;
883 bool isArraySubscriptRefExpr() const {
884 return getKeyExpr()->getType()->isIntegralOrEnumerationType();
887 child_range children() {
888 return child_range(SubExprs, SubExprs+END_EXPR);
891 static bool classof(const Stmt *T) {
892 return T->getStmtClass() == ObjCSubscriptRefExprClass;
896 friend class ASTStmtReader;
899 /// An expression that sends a message to the given Objective-C
902 /// The following contains two message send expressions:
905 /// [[NSString alloc] initWithString:@"Hello"]
908 /// The innermost message send invokes the "alloc" class method on the
909 /// NSString class, while the outermost message send invokes the
910 /// "initWithString" instance method on the object returned from
911 /// NSString's "alloc". In all, an Objective-C message send can take
912 /// on four different (although related) forms:
914 /// 1. Send to an object instance.
915 /// 2. Send to a class.
916 /// 3. Send to the superclass instance of the current class.
917 /// 4. Send to the superclass of the current class.
919 /// All four kinds of message sends are modeled by the ObjCMessageExpr
920 /// class, and can be distinguished via \c getReceiverKind(). Example:
922 /// The "void *" trailing objects are actually ONE void * (the
923 /// receiver pointer), and NumArgs Expr *. But due to the
924 /// implementation of children(), these must be together contiguously.
925 class ObjCMessageExpr final
927 private llvm::TrailingObjects<ObjCMessageExpr, void *, SourceLocation> {
928 /// Stores either the selector that this message is sending
929 /// to (when \c HasMethod is zero) or an \c ObjCMethodDecl pointer
930 /// referring to the method that we type-checked against.
931 uintptr_t SelectorOrMethod = 0;
933 enum { NumArgsBitWidth = 16 };
935 /// The number of arguments in the message send, not
936 /// including the receiver.
937 unsigned NumArgs : NumArgsBitWidth;
939 /// The kind of message send this is, which is one of the
940 /// ReceiverKind values.
942 /// We pad this out to a byte to avoid excessive masking and shifting.
945 /// Whether we have an actual method prototype in \c
946 /// SelectorOrMethod.
948 /// When non-zero, we have a method declaration; otherwise, we just
950 unsigned HasMethod : 1;
952 /// Whether this message send is a "delegate init call",
953 /// i.e. a call of an init method on self from within an init method.
954 unsigned IsDelegateInitCall : 1;
956 /// Whether this message send was implicitly generated by
957 /// the implementation rather than explicitly written by the user.
958 unsigned IsImplicit : 1;
960 /// Whether the locations of the selector identifiers are in a
961 /// "standard" position, a enum SelectorLocationsKind.
962 unsigned SelLocsKind : 2;
964 /// When the message expression is a send to 'super', this is
965 /// the location of the 'super' keyword.
966 SourceLocation SuperLoc;
968 /// The source locations of the open and close square
969 /// brackets ('[' and ']', respectively).
970 SourceLocation LBracLoc, RBracLoc;
972 ObjCMessageExpr(EmptyShell Empty, unsigned NumArgs)
973 : Expr(ObjCMessageExprClass, Empty), Kind(0), HasMethod(false),
974 IsDelegateInitCall(false), IsImplicit(false), SelLocsKind(0) {
978 ObjCMessageExpr(QualType T, ExprValueKind VK,
979 SourceLocation LBracLoc,
980 SourceLocation SuperLoc,
981 bool IsInstanceSuper,
984 ArrayRef<SourceLocation> SelLocs,
985 SelectorLocationsKind SelLocsK,
986 ObjCMethodDecl *Method,
987 ArrayRef<Expr *> Args,
988 SourceLocation RBracLoc,
990 ObjCMessageExpr(QualType T, ExprValueKind VK,
991 SourceLocation LBracLoc,
992 TypeSourceInfo *Receiver,
994 ArrayRef<SourceLocation> SelLocs,
995 SelectorLocationsKind SelLocsK,
996 ObjCMethodDecl *Method,
997 ArrayRef<Expr *> Args,
998 SourceLocation RBracLoc,
1000 ObjCMessageExpr(QualType T, ExprValueKind VK,
1001 SourceLocation LBracLoc,
1004 ArrayRef<SourceLocation> SelLocs,
1005 SelectorLocationsKind SelLocsK,
1006 ObjCMethodDecl *Method,
1007 ArrayRef<Expr *> Args,
1008 SourceLocation RBracLoc,
1011 size_t numTrailingObjects(OverloadToken<void *>) const { return NumArgs + 1; }
1013 void setNumArgs(unsigned Num) {
1014 assert((Num >> NumArgsBitWidth) == 0 && "Num of args is out of range!");
1018 void initArgsAndSelLocs(ArrayRef<Expr *> Args,
1019 ArrayRef<SourceLocation> SelLocs,
1020 SelectorLocationsKind SelLocsK);
1022 /// Retrieve the pointer value of the message receiver.
1023 void *getReceiverPointer() const { return *getTrailingObjects<void *>(); }
1025 /// Set the pointer value of the message receiver.
1026 void setReceiverPointer(void *Value) {
1027 *getTrailingObjects<void *>() = Value;
1030 SelectorLocationsKind getSelLocsKind() const {
1031 return (SelectorLocationsKind)SelLocsKind;
1034 bool hasStandardSelLocs() const {
1035 return getSelLocsKind() != SelLoc_NonStandard;
1038 /// Get a pointer to the stored selector identifiers locations array.
1039 /// No locations will be stored if HasStandardSelLocs is true.
1040 SourceLocation *getStoredSelLocs() {
1041 return getTrailingObjects<SourceLocation>();
1043 const SourceLocation *getStoredSelLocs() const {
1044 return getTrailingObjects<SourceLocation>();
1047 /// Get the number of stored selector identifiers locations.
1048 /// No locations will be stored if HasStandardSelLocs is true.
1049 unsigned getNumStoredSelLocs() const {
1050 if (hasStandardSelLocs())
1052 return getNumSelectorLocs();
1055 static ObjCMessageExpr *alloc(const ASTContext &C,
1056 ArrayRef<Expr *> Args,
1057 SourceLocation RBraceLoc,
1058 ArrayRef<SourceLocation> SelLocs,
1060 SelectorLocationsKind &SelLocsK);
1061 static ObjCMessageExpr *alloc(const ASTContext &C,
1063 unsigned NumStoredSelLocs);
1066 friend class ASTStmtReader;
1067 friend class ASTStmtWriter;
1068 friend TrailingObjects;
1070 /// The kind of receiver this message is sending to.
1072 /// The receiver is a class.
1075 /// The receiver is an object instance.
1078 /// The receiver is a superclass.
1081 /// The receiver is the instance of the superclass object.
1085 /// Create a message send to super.
1087 /// \param Context The ASTContext in which this expression will be created.
1089 /// \param T The result type of this message.
1091 /// \param VK The value kind of this message. A message returning
1092 /// a l-value or r-value reference will be an l-value or x-value,
1095 /// \param LBracLoc The location of the open square bracket '['.
1097 /// \param SuperLoc The location of the "super" keyword.
1099 /// \param IsInstanceSuper Whether this is an instance "super"
1100 /// message (otherwise, it's a class "super" message).
1102 /// \param Sel The selector used to determine which method gets called.
1104 /// \param Method The Objective-C method against which this message
1105 /// send was type-checked. May be nullptr.
1107 /// \param Args The message send arguments.
1109 /// \param RBracLoc The location of the closing square bracket ']'.
1110 static ObjCMessageExpr *Create(const ASTContext &Context, QualType T,
1112 SourceLocation LBracLoc,
1113 SourceLocation SuperLoc,
1114 bool IsInstanceSuper,
1117 ArrayRef<SourceLocation> SelLocs,
1118 ObjCMethodDecl *Method,
1119 ArrayRef<Expr *> Args,
1120 SourceLocation RBracLoc,
1123 /// Create a class message send.
1125 /// \param Context The ASTContext in which this expression will be created.
1127 /// \param T The result type of this message.
1129 /// \param VK The value kind of this message. A message returning
1130 /// a l-value or r-value reference will be an l-value or x-value,
1133 /// \param LBracLoc The location of the open square bracket '['.
1135 /// \param Receiver The type of the receiver, including
1136 /// source-location information.
1138 /// \param Sel The selector used to determine which method gets called.
1140 /// \param Method The Objective-C method against which this message
1141 /// send was type-checked. May be nullptr.
1143 /// \param Args The message send arguments.
1145 /// \param RBracLoc The location of the closing square bracket ']'.
1146 static ObjCMessageExpr *Create(const ASTContext &Context, QualType T,
1148 SourceLocation LBracLoc,
1149 TypeSourceInfo *Receiver,
1151 ArrayRef<SourceLocation> SelLocs,
1152 ObjCMethodDecl *Method,
1153 ArrayRef<Expr *> Args,
1154 SourceLocation RBracLoc,
1157 /// Create an instance message send.
1159 /// \param Context The ASTContext in which this expression will be created.
1161 /// \param T The result type of this message.
1163 /// \param VK The value kind of this message. A message returning
1164 /// a l-value or r-value reference will be an l-value or x-value,
1167 /// \param LBracLoc The location of the open square bracket '['.
1169 /// \param Receiver The expression used to produce the object that
1170 /// will receive this message.
1172 /// \param Sel The selector used to determine which method gets called.
1174 /// \param Method The Objective-C method against which this message
1175 /// send was type-checked. May be nullptr.
1177 /// \param Args The message send arguments.
1179 /// \param RBracLoc The location of the closing square bracket ']'.
1180 static ObjCMessageExpr *Create(const ASTContext &Context, QualType T,
1182 SourceLocation LBracLoc,
1185 ArrayRef<SourceLocation> SeLocs,
1186 ObjCMethodDecl *Method,
1187 ArrayRef<Expr *> Args,
1188 SourceLocation RBracLoc,
1191 /// Create an empty Objective-C message expression, to be
1192 /// filled in by subsequent calls.
1194 /// \param Context The context in which the message send will be created.
1196 /// \param NumArgs The number of message arguments, not including
1198 static ObjCMessageExpr *CreateEmpty(const ASTContext &Context,
1200 unsigned NumStoredSelLocs);
1202 /// Indicates whether the message send was implicitly
1203 /// generated by the implementation. If false, it was written explicitly
1204 /// in the source code.
1205 bool isImplicit() const { return IsImplicit; }
1207 /// Determine the kind of receiver that this message is being
1209 ReceiverKind getReceiverKind() const { return (ReceiverKind)Kind; }
1211 /// Source range of the receiver.
1212 SourceRange getReceiverRange() const;
1214 /// Determine whether this is an instance message to either a
1215 /// computed object or to super.
1216 bool isInstanceMessage() const {
1217 return getReceiverKind() == Instance || getReceiverKind() == SuperInstance;
1220 /// Determine whether this is an class message to either a
1221 /// specified class or to super.
1222 bool isClassMessage() const {
1223 return getReceiverKind() == Class || getReceiverKind() == SuperClass;
1226 /// Returns the object expression (receiver) for an instance message,
1227 /// or null for a message that is not an instance message.
1228 Expr *getInstanceReceiver() {
1229 if (getReceiverKind() == Instance)
1230 return static_cast<Expr *>(getReceiverPointer());
1234 const Expr *getInstanceReceiver() const {
1235 return const_cast<ObjCMessageExpr*>(this)->getInstanceReceiver();
1238 /// Turn this message send into an instance message that
1239 /// computes the receiver object with the given expression.
1240 void setInstanceReceiver(Expr *rec) {
1242 setReceiverPointer(rec);
1245 /// Returns the type of a class message send, or NULL if the
1246 /// message is not a class message.
1247 QualType getClassReceiver() const {
1248 if (TypeSourceInfo *TSInfo = getClassReceiverTypeInfo())
1249 return TSInfo->getType();
1254 /// Returns a type-source information of a class message
1255 /// send, or nullptr if the message is not a class message.
1256 TypeSourceInfo *getClassReceiverTypeInfo() const {
1257 if (getReceiverKind() == Class)
1258 return reinterpret_cast<TypeSourceInfo *>(getReceiverPointer());
1262 void setClassReceiver(TypeSourceInfo *TSInfo) {
1264 setReceiverPointer(TSInfo);
1267 /// Retrieve the location of the 'super' keyword for a class
1268 /// or instance message to 'super', otherwise an invalid source location.
1269 SourceLocation getSuperLoc() const {
1270 if (getReceiverKind() == SuperInstance || getReceiverKind() == SuperClass)
1273 return SourceLocation();
1276 /// Retrieve the receiver type to which this message is being directed.
1278 /// This routine cross-cuts all of the different kinds of message
1279 /// sends to determine what the underlying (statically known) type
1280 /// of the receiver will be; use \c getReceiverKind() to determine
1281 /// whether the message is a class or an instance method, whether it
1282 /// is a send to super or not, etc.
1284 /// \returns The type of the receiver.
1285 QualType getReceiverType() const;
1287 /// Retrieve the Objective-C interface to which this message
1288 /// is being directed, if known.
1290 /// This routine cross-cuts all of the different kinds of message
1291 /// sends to determine what the underlying (statically known) type
1292 /// of the receiver will be; use \c getReceiverKind() to determine
1293 /// whether the message is a class or an instance method, whether it
1294 /// is a send to super or not, etc.
1296 /// \returns The Objective-C interface if known, otherwise nullptr.
1297 ObjCInterfaceDecl *getReceiverInterface() const;
1299 /// Retrieve the type referred to by 'super'.
1301 /// The returned type will either be an ObjCInterfaceType (for an
1302 /// class message to super) or an ObjCObjectPointerType that refers
1303 /// to a class (for an instance message to super);
1304 QualType getSuperType() const {
1305 if (getReceiverKind() == SuperInstance || getReceiverKind() == SuperClass)
1306 return QualType::getFromOpaquePtr(getReceiverPointer());
1311 void setSuper(SourceLocation Loc, QualType T, bool IsInstanceSuper) {
1312 Kind = IsInstanceSuper? SuperInstance : SuperClass;
1314 setReceiverPointer(T.getAsOpaquePtr());
1317 Selector getSelector() const;
1319 void setSelector(Selector S) {
1321 SelectorOrMethod = reinterpret_cast<uintptr_t>(S.getAsOpaquePtr());
1324 const ObjCMethodDecl *getMethodDecl() const {
1326 return reinterpret_cast<const ObjCMethodDecl *>(SelectorOrMethod);
1331 ObjCMethodDecl *getMethodDecl() {
1333 return reinterpret_cast<ObjCMethodDecl *>(SelectorOrMethod);
1338 void setMethodDecl(ObjCMethodDecl *MD) {
1340 SelectorOrMethod = reinterpret_cast<uintptr_t>(MD);
1343 ObjCMethodFamily getMethodFamily() const {
1344 if (HasMethod) return getMethodDecl()->getMethodFamily();
1345 return getSelector().getMethodFamily();
1348 /// Return the number of actual arguments in this message,
1349 /// not counting the receiver.
1350 unsigned getNumArgs() const { return NumArgs; }
1352 /// Retrieve the arguments to this message, not including the
1355 return reinterpret_cast<Expr **>(getTrailingObjects<void *>() + 1);
1357 const Expr * const *getArgs() const {
1358 return reinterpret_cast<const Expr *const *>(getTrailingObjects<void *>() +
1362 /// getArg - Return the specified argument.
1363 Expr *getArg(unsigned Arg) {
1364 assert(Arg < NumArgs && "Arg access out of range!");
1365 return getArgs()[Arg];
1367 const Expr *getArg(unsigned Arg) const {
1368 assert(Arg < NumArgs && "Arg access out of range!");
1369 return getArgs()[Arg];
1372 /// setArg - Set the specified argument.
1373 void setArg(unsigned Arg, Expr *ArgExpr) {
1374 assert(Arg < NumArgs && "Arg access out of range!");
1375 getArgs()[Arg] = ArgExpr;
1378 /// isDelegateInitCall - Answers whether this message send has been
1379 /// tagged as a "delegate init call", i.e. a call to a method in the
1380 /// -init family on self from within an -init method implementation.
1381 bool isDelegateInitCall() const { return IsDelegateInitCall; }
1382 void setDelegateInitCall(bool isDelegate) { IsDelegateInitCall = isDelegate; }
1384 SourceLocation getLeftLoc() const { return LBracLoc; }
1385 SourceLocation getRightLoc() const { return RBracLoc; }
1387 SourceLocation getSelectorStartLoc() const {
1389 return getLocStart();
1390 return getSelectorLoc(0);
1393 SourceLocation getSelectorLoc(unsigned Index) const {
1394 assert(Index < getNumSelectorLocs() && "Index out of range!");
1395 if (hasStandardSelLocs())
1396 return getStandardSelectorLoc(Index, getSelector(),
1397 getSelLocsKind() == SelLoc_StandardWithSpace,
1398 llvm::makeArrayRef(const_cast<Expr**>(getArgs()),
1401 return getStoredSelLocs()[Index];
1404 void getSelectorLocs(SmallVectorImpl<SourceLocation> &SelLocs) const;
1406 unsigned getNumSelectorLocs() const {
1409 Selector Sel = getSelector();
1410 if (Sel.isUnarySelector())
1412 return Sel.getNumArgs();
1415 void setSourceRange(SourceRange R) {
1416 LBracLoc = R.getBegin();
1417 RBracLoc = R.getEnd();
1420 SourceLocation getLocStart() const LLVM_READONLY { return getBeginLoc(); }
1421 SourceLocation getBeginLoc() const LLVM_READONLY { return LBracLoc; }
1422 SourceLocation getLocEnd() const LLVM_READONLY { return getEndLoc(); }
1423 SourceLocation getEndLoc() const LLVM_READONLY { return RBracLoc; }
1426 child_range children();
1428 using arg_iterator = ExprIterator;
1429 using const_arg_iterator = ConstExprIterator;
1431 llvm::iterator_range<arg_iterator> arguments() {
1432 return llvm::make_range(arg_begin(), arg_end());
1435 llvm::iterator_range<const_arg_iterator> arguments() const {
1436 return llvm::make_range(arg_begin(), arg_end());
1439 arg_iterator arg_begin() { return reinterpret_cast<Stmt **>(getArgs()); }
1441 arg_iterator arg_end() {
1442 return reinterpret_cast<Stmt **>(getArgs() + NumArgs);
1445 const_arg_iterator arg_begin() const {
1446 return reinterpret_cast<Stmt const * const*>(getArgs());
1449 const_arg_iterator arg_end() const {
1450 return reinterpret_cast<Stmt const * const*>(getArgs() + NumArgs);
1453 static bool classof(const Stmt *T) {
1454 return T->getStmtClass() == ObjCMessageExprClass;
1458 /// ObjCIsaExpr - Represent X->isa and X.isa when X is an ObjC 'id' type.
1459 /// (similar in spirit to MemberExpr).
1460 class ObjCIsaExpr : public Expr {
1461 /// Base - the expression for the base object pointer.
1464 /// IsaMemberLoc - This is the location of the 'isa'.
1465 SourceLocation IsaMemberLoc;
1467 /// OpLoc - This is the location of '.' or '->'
1468 SourceLocation OpLoc;
1470 /// IsArrow - True if this is "X->F", false if this is "X.F".
1474 ObjCIsaExpr(Expr *base, bool isarrow, SourceLocation l, SourceLocation oploc,
1476 : Expr(ObjCIsaExprClass, ty, VK_LValue, OK_Ordinary,
1477 /*TypeDependent=*/false, base->isValueDependent(),
1478 base->isInstantiationDependent(),
1479 /*ContainsUnexpandedParameterPack=*/false),
1480 Base(base), IsaMemberLoc(l), OpLoc(oploc), IsArrow(isarrow) {}
1482 /// Build an empty expression.
1483 explicit ObjCIsaExpr(EmptyShell Empty) : Expr(ObjCIsaExprClass, Empty) {}
1485 void setBase(Expr *E) { Base = E; }
1486 Expr *getBase() const { return cast<Expr>(Base); }
1488 bool isArrow() const { return IsArrow; }
1489 void setArrow(bool A) { IsArrow = A; }
1491 /// getMemberLoc - Return the location of the "member", in X->F, it is the
1492 /// location of 'F'.
1493 SourceLocation getIsaMemberLoc() const { return IsaMemberLoc; }
1494 void setIsaMemberLoc(SourceLocation L) { IsaMemberLoc = L; }
1496 SourceLocation getOpLoc() const { return OpLoc; }
1497 void setOpLoc(SourceLocation L) { OpLoc = L; }
1499 SourceLocation getLocStart() const LLVM_READONLY { return getBeginLoc(); }
1500 SourceLocation getBeginLoc() const LLVM_READONLY {
1501 return getBase()->getLocStart();
1504 SourceLocation getBaseLocEnd() const LLVM_READONLY {
1505 return getBase()->getLocEnd();
1508 SourceLocation getLocEnd() const LLVM_READONLY { return getEndLoc(); }
1509 SourceLocation getEndLoc() const LLVM_READONLY { return IsaMemberLoc; }
1511 SourceLocation getExprLoc() const LLVM_READONLY { return IsaMemberLoc; }
1514 child_range children() { return child_range(&Base, &Base+1); }
1516 static bool classof(const Stmt *T) {
1517 return T->getStmtClass() == ObjCIsaExprClass;
1521 /// ObjCIndirectCopyRestoreExpr - Represents the passing of a function
1522 /// argument by indirect copy-restore in ARC. This is used to support
1523 /// passing indirect arguments with the wrong lifetime, e.g. when
1524 /// passing the address of a __strong local variable to an 'out'
1525 /// parameter. This expression kind is only valid in an "argument"
1526 /// position to some sort of call expression.
1528 /// The parameter must have type 'pointer to T', and the argument must
1529 /// have type 'pointer to U', where T and U agree except possibly in
1530 /// qualification. If the argument value is null, then a null pointer
1531 /// is passed; otherwise it points to an object A, and:
1532 /// 1. A temporary object B of type T is initialized, either by
1533 /// zero-initialization (used when initializing an 'out' parameter)
1534 /// or copy-initialization (used when initializing an 'inout'
1536 /// 2. The address of the temporary is passed to the function.
1537 /// 3. If the call completes normally, A is move-assigned from B.
1538 /// 4. Finally, A is destroyed immediately.
1540 /// Currently 'T' must be a retainable object lifetime and must be
1541 /// __autoreleasing; this qualifier is ignored when initializing
1543 class ObjCIndirectCopyRestoreExpr : public Expr {
1544 friend class ASTReader;
1545 friend class ASTStmtReader;
1549 // unsigned ObjCIndirectCopyRestoreBits.ShouldCopy : 1;
1551 explicit ObjCIndirectCopyRestoreExpr(EmptyShell Empty)
1552 : Expr(ObjCIndirectCopyRestoreExprClass, Empty) {}
1554 void setShouldCopy(bool shouldCopy) {
1555 ObjCIndirectCopyRestoreExprBits.ShouldCopy = shouldCopy;
1559 ObjCIndirectCopyRestoreExpr(Expr *operand, QualType type, bool shouldCopy)
1560 : Expr(ObjCIndirectCopyRestoreExprClass, type, VK_LValue, OK_Ordinary,
1561 operand->isTypeDependent(), operand->isValueDependent(),
1562 operand->isInstantiationDependent(),
1563 operand->containsUnexpandedParameterPack()),
1565 setShouldCopy(shouldCopy);
1568 Expr *getSubExpr() { return cast<Expr>(Operand); }
1569 const Expr *getSubExpr() const { return cast<Expr>(Operand); }
1571 /// shouldCopy - True if we should do the 'copy' part of the
1572 /// copy-restore. If false, the temporary will be zero-initialized.
1573 bool shouldCopy() const { return ObjCIndirectCopyRestoreExprBits.ShouldCopy; }
1575 child_range children() { return child_range(&Operand, &Operand+1); }
1577 // Source locations are determined by the subexpression.
1578 SourceLocation getLocStart() const LLVM_READONLY { return getBeginLoc(); }
1579 SourceLocation getBeginLoc() const LLVM_READONLY {
1580 return Operand->getLocStart();
1582 SourceLocation getLocEnd() const LLVM_READONLY { return getEndLoc(); }
1583 SourceLocation getEndLoc() const LLVM_READONLY {
1584 return Operand->getLocEnd();
1587 SourceLocation getExprLoc() const LLVM_READONLY {
1588 return getSubExpr()->getExprLoc();
1591 static bool classof(const Stmt *s) {
1592 return s->getStmtClass() == ObjCIndirectCopyRestoreExprClass;
1596 /// An Objective-C "bridged" cast expression, which casts between
1597 /// Objective-C pointers and C pointers, transferring ownership in the process.
1600 /// NSString *str = (__bridge_transfer NSString *)CFCreateString();
1602 class ObjCBridgedCastExpr final
1603 : public ExplicitCastExpr,
1604 private llvm::TrailingObjects<
1605 ObjCBridgedCastExpr, CastExpr::BasePathSizeTy, CXXBaseSpecifier *> {
1606 friend class ASTStmtReader;
1607 friend class ASTStmtWriter;
1608 friend class CastExpr;
1609 friend TrailingObjects;
1611 SourceLocation LParenLoc;
1612 SourceLocation BridgeKeywordLoc;
1615 size_t numTrailingObjects(OverloadToken<CastExpr::BasePathSizeTy>) const {
1616 return path_empty() ? 0 : 1;
1620 ObjCBridgedCastExpr(SourceLocation LParenLoc, ObjCBridgeCastKind Kind,
1621 CastKind CK, SourceLocation BridgeKeywordLoc,
1622 TypeSourceInfo *TSInfo, Expr *Operand)
1623 : ExplicitCastExpr(ObjCBridgedCastExprClass, TSInfo->getType(), VK_RValue,
1624 CK, Operand, 0, TSInfo),
1625 LParenLoc(LParenLoc), BridgeKeywordLoc(BridgeKeywordLoc), Kind(Kind) {}
1627 /// Construct an empty Objective-C bridged cast.
1628 explicit ObjCBridgedCastExpr(EmptyShell Shell)
1629 : ExplicitCastExpr(ObjCBridgedCastExprClass, Shell, 0) {}
1631 SourceLocation getLParenLoc() const { return LParenLoc; }
1633 /// Determine which kind of bridge is being performed via this cast.
1634 ObjCBridgeCastKind getBridgeKind() const {
1635 return static_cast<ObjCBridgeCastKind>(Kind);
1638 /// Retrieve the kind of bridge being performed as a string.
1639 StringRef getBridgeKindName() const;
1641 /// The location of the bridge keyword.
1642 SourceLocation getBridgeKeywordLoc() const { return BridgeKeywordLoc; }
1644 SourceLocation getLocStart() const LLVM_READONLY { return getBeginLoc(); }
1645 SourceLocation getBeginLoc() const LLVM_READONLY { return LParenLoc; }
1647 SourceLocation getLocEnd() const LLVM_READONLY { return getEndLoc(); }
1648 SourceLocation getEndLoc() const LLVM_READONLY {
1649 return getSubExpr()->getLocEnd();
1652 static bool classof(const Stmt *T) {
1653 return T->getStmtClass() == ObjCBridgedCastExprClass;
1657 /// A runtime availability query.
1659 /// There are 2 ways to spell this node:
1661 /// @available(macos 10.10, ios 8, *); // Objective-C
1662 /// __builtin_available(macos 10.10, ios 8, *); // C, C++, and Objective-C
1665 /// Note that we only need to keep track of one \c VersionTuple here, which is
1666 /// the one that corresponds to the current deployment target. This is meant to
1667 /// be used in the condition of an \c if, but it is also usable as top level
1670 class ObjCAvailabilityCheckExpr : public Expr {
1671 friend class ASTStmtReader;
1673 VersionTuple VersionToCheck;
1674 SourceLocation AtLoc, RParen;
1677 ObjCAvailabilityCheckExpr(VersionTuple VersionToCheck, SourceLocation AtLoc,
1678 SourceLocation RParen, QualType Ty)
1679 : Expr(ObjCAvailabilityCheckExprClass, Ty, VK_RValue, OK_Ordinary, false,
1680 false, false, false),
1681 VersionToCheck(VersionToCheck), AtLoc(AtLoc), RParen(RParen) {}
1683 explicit ObjCAvailabilityCheckExpr(EmptyShell Shell)
1684 : Expr(ObjCAvailabilityCheckExprClass, Shell) {}
1686 SourceLocation getLocStart() const LLVM_READONLY { return getBeginLoc(); }
1687 SourceLocation getBeginLoc() const { return AtLoc; }
1688 SourceLocation getLocEnd() const LLVM_READONLY { return getEndLoc(); }
1689 SourceLocation getEndLoc() const { return RParen; }
1690 SourceRange getSourceRange() const { return {AtLoc, RParen}; }
1692 /// This may be '*', in which case this should fold to true.
1693 bool hasVersion() const { return !VersionToCheck.empty(); }
1694 VersionTuple getVersion() { return VersionToCheck; }
1696 child_range children() {
1697 return child_range(child_iterator(), child_iterator());
1700 static bool classof(const Stmt *T) {
1701 return T->getStmtClass() == ObjCAvailabilityCheckExprClass;
1705 } // namespace clang
1707 #endif // LLVM_CLANG_AST_EXPROBJC_H