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 "clang/Basic/VersionTuple.h"
29 #include "llvm/ADT/ArrayRef.h"
30 #include "llvm/ADT/None.h"
31 #include "llvm/ADT/Optional.h"
32 #include "llvm/ADT/PointerIntPair.h"
33 #include "llvm/ADT/PointerUnion.h"
34 #include "llvm/ADT/StringRef.h"
35 #include "llvm/ADT/iterator_range.h"
36 #include "llvm/Support/Casting.h"
37 #include "llvm/Support/Compiler.h"
38 #include "llvm/Support/TrailingObjects.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 AtLoc; }
71 SourceLocation getLocEnd() const LLVM_READONLY { return String->getLocEnd(); }
74 child_range children() { return child_range(&String, &String+1); }
76 static bool classof(const Stmt *T) {
77 return T->getStmtClass() == ObjCStringLiteralClass;
81 /// ObjCBoolLiteralExpr - Objective-C Boolean Literal.
82 class ObjCBoolLiteralExpr : public Expr {
87 ObjCBoolLiteralExpr(bool val, QualType Ty, SourceLocation l)
88 : Expr(ObjCBoolLiteralExprClass, Ty, VK_RValue, OK_Ordinary, false, false,
91 explicit ObjCBoolLiteralExpr(EmptyShell Empty)
92 : Expr(ObjCBoolLiteralExprClass, Empty) {}
94 bool getValue() const { return Value; }
95 void setValue(bool V) { Value = V; }
97 SourceLocation getLocStart() const LLVM_READONLY { return Loc; }
98 SourceLocation getLocEnd() const LLVM_READONLY { return Loc; }
100 SourceLocation getLocation() const { return Loc; }
101 void setLocation(SourceLocation L) { Loc = L; }
104 child_range children() {
105 return child_range(child_iterator(), child_iterator());
108 static bool classof(const Stmt *T) {
109 return T->getStmtClass() == ObjCBoolLiteralExprClass;
113 /// ObjCBoxedExpr - used for generalized expression boxing.
114 /// as in: @(strdup("hello world")), @(random()) or @(view.frame)
115 /// Also used for boxing non-parenthesized numeric literals;
116 /// as in: @42 or \@true (c++/objc++) or \@__objc_yes (c/objc).
117 class ObjCBoxedExpr : public Expr {
119 ObjCMethodDecl *BoxingMethod;
123 friend class ASTStmtReader;
125 ObjCBoxedExpr(Expr *E, QualType T, ObjCMethodDecl *method,
127 : Expr(ObjCBoxedExprClass, T, VK_RValue, OK_Ordinary,
128 E->isTypeDependent(), E->isValueDependent(),
129 E->isInstantiationDependent(),
130 E->containsUnexpandedParameterPack()),
131 SubExpr(E), BoxingMethod(method), Range(R) {}
132 explicit ObjCBoxedExpr(EmptyShell Empty)
133 : Expr(ObjCBoxedExprClass, Empty) {}
135 Expr *getSubExpr() { return cast<Expr>(SubExpr); }
136 const Expr *getSubExpr() const { return cast<Expr>(SubExpr); }
138 ObjCMethodDecl *getBoxingMethod() const {
142 SourceLocation getAtLoc() const { return Range.getBegin(); }
144 SourceLocation getLocStart() const LLVM_READONLY { return Range.getBegin(); }
145 SourceLocation getLocEnd() const LLVM_READONLY { return Range.getEnd(); }
147 SourceRange getSourceRange() const LLVM_READONLY {
152 child_range children() { return child_range(&SubExpr, &SubExpr+1); }
154 using const_arg_iterator = ConstExprIterator;
156 const_arg_iterator arg_begin() const {
157 return reinterpret_cast<Stmt const * const*>(&SubExpr);
160 const_arg_iterator arg_end() const {
161 return reinterpret_cast<Stmt const * const*>(&SubExpr + 1);
164 static bool classof(const Stmt *T) {
165 return T->getStmtClass() == ObjCBoxedExprClass;
169 /// ObjCArrayLiteral - used for objective-c array containers; as in:
170 /// @[@"Hello", NSApp, [NSNumber numberWithInt:42]];
171 class ObjCArrayLiteral final
173 private llvm::TrailingObjects<ObjCArrayLiteral, Expr *> {
174 unsigned NumElements;
176 ObjCMethodDecl *ArrayWithObjectsMethod;
178 ObjCArrayLiteral(ArrayRef<Expr *> Elements,
179 QualType T, ObjCMethodDecl * Method,
182 explicit ObjCArrayLiteral(EmptyShell Empty, unsigned NumElements)
183 : Expr(ObjCArrayLiteralClass, Empty), NumElements(NumElements) {}
186 friend class ASTStmtReader;
187 friend TrailingObjects;
189 static ObjCArrayLiteral *Create(const ASTContext &C,
190 ArrayRef<Expr *> Elements,
191 QualType T, ObjCMethodDecl * Method,
194 static ObjCArrayLiteral *CreateEmpty(const ASTContext &C,
195 unsigned NumElements);
197 SourceLocation getLocStart() const LLVM_READONLY { return Range.getBegin(); }
198 SourceLocation getLocEnd() const LLVM_READONLY { return Range.getEnd(); }
199 SourceRange getSourceRange() const LLVM_READONLY { return Range; }
201 /// \brief Retrieve elements of array of literals.
202 Expr **getElements() { return getTrailingObjects<Expr *>(); }
204 /// \brief Retrieve elements of array of literals.
205 const Expr * const *getElements() const {
206 return getTrailingObjects<Expr *>();
209 /// getNumElements - Return number of elements of objective-c array literal.
210 unsigned getNumElements() const { return NumElements; }
212 /// getElement - Return the Element at the specified index.
213 Expr *getElement(unsigned Index) {
214 assert((Index < NumElements) && "Arg access out of range!");
215 return cast<Expr>(getElements()[Index]);
217 const Expr *getElement(unsigned Index) const {
218 assert((Index < NumElements) && "Arg access out of range!");
219 return cast<Expr>(getElements()[Index]);
222 ObjCMethodDecl *getArrayWithObjectsMethod() const {
223 return ArrayWithObjectsMethod;
227 child_range children() {
228 return child_range(reinterpret_cast<Stmt **>(getElements()),
229 reinterpret_cast<Stmt **>(getElements()) + NumElements);
232 static bool classof(const Stmt *T) {
233 return T->getStmtClass() == ObjCArrayLiteralClass;
237 /// \brief An element in an Objective-C dictionary literal.
239 struct ObjCDictionaryElement {
240 /// \brief The key for the dictionary element.
243 /// \brief The value of the dictionary element.
246 /// \brief The location of the ellipsis, if this is a pack expansion.
247 SourceLocation EllipsisLoc;
249 /// \brief The number of elements this pack expansion will expand to, if
250 /// this is a pack expansion and is known.
251 Optional<unsigned> NumExpansions;
253 /// \brief Determines whether this dictionary element is a pack expansion.
254 bool isPackExpansion() const { return EllipsisLoc.isValid(); }
261 template <> struct isPodLike<clang::ObjCDictionaryElement> : std::true_type {};
267 /// \brief Internal struct for storing Key/value pair.
268 struct ObjCDictionaryLiteral_KeyValuePair {
273 /// \brief Internal struct to describes an element that is a pack
274 /// expansion, used if any of the elements in the dictionary literal
275 /// are pack expansions.
276 struct ObjCDictionaryLiteral_ExpansionData {
277 /// \brief The location of the ellipsis, if this element is a pack
279 SourceLocation EllipsisLoc;
281 /// \brief If non-zero, the number of elements that this pack
282 /// expansion will expand to (+1).
283 unsigned NumExpansionsPlusOne;
286 /// ObjCDictionaryLiteral - AST node to represent objective-c dictionary
287 /// literals; as in: @{@"name" : NSUserName(), @"date" : [NSDate date] };
288 class ObjCDictionaryLiteral final
290 private llvm::TrailingObjects<ObjCDictionaryLiteral,
291 ObjCDictionaryLiteral_KeyValuePair,
292 ObjCDictionaryLiteral_ExpansionData> {
293 /// \brief The number of elements in this dictionary literal.
294 unsigned NumElements : 31;
296 /// \brief Determine whether this dictionary literal has any pack expansions.
298 /// If the dictionary literal has pack expansions, then there will
299 /// be an array of pack expansion data following the array of
300 /// key/value pairs, which provide the locations of the ellipses (if
301 /// any) and number of elements in the expansion (if known). If
302 /// there are no pack expansions, we optimize away this storage.
303 unsigned HasPackExpansions : 1;
306 ObjCMethodDecl *DictWithObjectsMethod;
308 using KeyValuePair = ObjCDictionaryLiteral_KeyValuePair;
309 using ExpansionData = ObjCDictionaryLiteral_ExpansionData;
311 ObjCDictionaryLiteral(ArrayRef<ObjCDictionaryElement> VK,
312 bool HasPackExpansions,
313 QualType T, ObjCMethodDecl *method,
316 explicit ObjCDictionaryLiteral(EmptyShell Empty, unsigned NumElements,
317 bool HasPackExpansions)
318 : Expr(ObjCDictionaryLiteralClass, Empty), NumElements(NumElements),
319 HasPackExpansions(HasPackExpansions) {}
321 size_t numTrailingObjects(OverloadToken<KeyValuePair>) const {
326 friend class ASTStmtReader;
327 friend class ASTStmtWriter;
328 friend TrailingObjects;
330 static ObjCDictionaryLiteral *Create(const ASTContext &C,
331 ArrayRef<ObjCDictionaryElement> VK,
332 bool HasPackExpansions,
333 QualType T, ObjCMethodDecl *method,
336 static ObjCDictionaryLiteral *CreateEmpty(const ASTContext &C,
337 unsigned NumElements,
338 bool HasPackExpansions);
340 /// getNumElements - Return number of elements of objective-c dictionary
342 unsigned getNumElements() const { return NumElements; }
344 ObjCDictionaryElement getKeyValueElement(unsigned Index) const {
345 assert((Index < NumElements) && "Arg access out of range!");
346 const KeyValuePair &KV = getTrailingObjects<KeyValuePair>()[Index];
347 ObjCDictionaryElement Result = { KV.Key, KV.Value, SourceLocation(), None };
348 if (HasPackExpansions) {
349 const ExpansionData &Expansion =
350 getTrailingObjects<ExpansionData>()[Index];
351 Result.EllipsisLoc = Expansion.EllipsisLoc;
352 if (Expansion.NumExpansionsPlusOne > 0)
353 Result.NumExpansions = Expansion.NumExpansionsPlusOne - 1;
358 ObjCMethodDecl *getDictWithObjectsMethod() const {
359 return DictWithObjectsMethod;
362 SourceLocation getLocStart() const LLVM_READONLY { return Range.getBegin(); }
363 SourceLocation getLocEnd() const LLVM_READONLY { return Range.getEnd(); }
364 SourceRange getSourceRange() const LLVM_READONLY { return Range; }
367 child_range children() {
368 // Note: we're taking advantage of the layout of the KeyValuePair struct
369 // here. If that struct changes, this code will need to change as well.
370 static_assert(sizeof(KeyValuePair) == sizeof(Stmt *) * 2,
371 "KeyValuePair is expected size");
373 reinterpret_cast<Stmt **>(getTrailingObjects<KeyValuePair>()),
374 reinterpret_cast<Stmt **>(getTrailingObjects<KeyValuePair>()) +
378 static bool classof(const Stmt *T) {
379 return T->getStmtClass() == ObjCDictionaryLiteralClass;
383 /// ObjCEncodeExpr, used for \@encode in Objective-C. \@encode has the same
384 /// type and behavior as StringLiteral except that the string initializer is
385 /// obtained from ASTContext with the encoding type as an argument.
386 class ObjCEncodeExpr : public Expr {
387 TypeSourceInfo *EncodedType;
388 SourceLocation AtLoc, RParenLoc;
391 ObjCEncodeExpr(QualType T, TypeSourceInfo *EncodedType,
392 SourceLocation at, SourceLocation rp)
393 : Expr(ObjCEncodeExprClass, T, VK_LValue, OK_Ordinary,
394 EncodedType->getType()->isDependentType(),
395 EncodedType->getType()->isDependentType(),
396 EncodedType->getType()->isInstantiationDependentType(),
397 EncodedType->getType()->containsUnexpandedParameterPack()),
398 EncodedType(EncodedType), AtLoc(at), RParenLoc(rp) {}
400 explicit ObjCEncodeExpr(EmptyShell Empty) : Expr(ObjCEncodeExprClass, Empty){}
402 SourceLocation getAtLoc() const { return AtLoc; }
403 void setAtLoc(SourceLocation L) { AtLoc = L; }
404 SourceLocation getRParenLoc() const { return RParenLoc; }
405 void setRParenLoc(SourceLocation L) { RParenLoc = L; }
407 QualType getEncodedType() const { return EncodedType->getType(); }
409 TypeSourceInfo *getEncodedTypeSourceInfo() const { return EncodedType; }
411 void setEncodedTypeSourceInfo(TypeSourceInfo *EncType) {
412 EncodedType = EncType;
415 SourceLocation getLocStart() const LLVM_READONLY { return AtLoc; }
416 SourceLocation getLocEnd() const LLVM_READONLY { return RParenLoc; }
419 child_range children() {
420 return child_range(child_iterator(), child_iterator());
423 static bool classof(const Stmt *T) {
424 return T->getStmtClass() == ObjCEncodeExprClass;
428 /// ObjCSelectorExpr used for \@selector in Objective-C.
429 class ObjCSelectorExpr : public Expr {
431 SourceLocation AtLoc, RParenLoc;
434 ObjCSelectorExpr(QualType T, Selector selInfo,
435 SourceLocation at, SourceLocation rp)
436 : Expr(ObjCSelectorExprClass, T, VK_RValue, OK_Ordinary, false, false,
438 SelName(selInfo), AtLoc(at), RParenLoc(rp) {}
439 explicit ObjCSelectorExpr(EmptyShell Empty)
440 : Expr(ObjCSelectorExprClass, Empty) {}
442 Selector getSelector() const { return SelName; }
443 void setSelector(Selector S) { SelName = S; }
445 SourceLocation getAtLoc() const { return AtLoc; }
446 SourceLocation getRParenLoc() const { return RParenLoc; }
447 void setAtLoc(SourceLocation L) { AtLoc = L; }
448 void setRParenLoc(SourceLocation L) { RParenLoc = L; }
450 SourceLocation getLocStart() const LLVM_READONLY { return AtLoc; }
451 SourceLocation getLocEnd() const LLVM_READONLY { return RParenLoc; }
453 /// getNumArgs - Return the number of actual arguments to this call.
454 unsigned getNumArgs() const { return SelName.getNumArgs(); }
457 child_range children() {
458 return child_range(child_iterator(), child_iterator());
461 static bool classof(const Stmt *T) {
462 return T->getStmtClass() == ObjCSelectorExprClass;
466 /// ObjCProtocolExpr used for protocol expression in Objective-C.
468 /// This is used as: \@protocol(foo), as in:
470 /// [obj conformsToProtocol:@protocol(foo)]
473 /// The return type is "Protocol*".
474 class ObjCProtocolExpr : public Expr {
475 ObjCProtocolDecl *TheProtocol;
476 SourceLocation AtLoc, ProtoLoc, RParenLoc;
479 friend class ASTStmtReader;
480 friend class ASTStmtWriter;
482 ObjCProtocolExpr(QualType T, ObjCProtocolDecl *protocol,
483 SourceLocation at, SourceLocation protoLoc, SourceLocation rp)
484 : Expr(ObjCProtocolExprClass, T, VK_RValue, OK_Ordinary, false, false,
486 TheProtocol(protocol), AtLoc(at), ProtoLoc(protoLoc), RParenLoc(rp) {}
487 explicit ObjCProtocolExpr(EmptyShell Empty)
488 : Expr(ObjCProtocolExprClass, Empty) {}
490 ObjCProtocolDecl *getProtocol() const { return TheProtocol; }
491 void setProtocol(ObjCProtocolDecl *P) { TheProtocol = P; }
493 SourceLocation getProtocolIdLoc() const { return ProtoLoc; }
494 SourceLocation getAtLoc() const { return AtLoc; }
495 SourceLocation getRParenLoc() const { return RParenLoc; }
496 void setAtLoc(SourceLocation L) { AtLoc = L; }
497 void setRParenLoc(SourceLocation L) { RParenLoc = L; }
499 SourceLocation getLocStart() const LLVM_READONLY { return AtLoc; }
500 SourceLocation getLocEnd() const LLVM_READONLY { return RParenLoc; }
503 child_range children() {
504 return child_range(child_iterator(), child_iterator());
507 static bool classof(const Stmt *T) {
508 return T->getStmtClass() == ObjCProtocolExprClass;
512 /// ObjCIvarRefExpr - A reference to an ObjC instance variable.
513 class ObjCIvarRefExpr : public Expr {
518 /// OpLoc - This is the location of '.' or '->'
519 SourceLocation OpLoc;
521 // True if this is "X->F", false if this is "X.F".
524 // True if ivar reference has no base (self assumed).
528 ObjCIvarRefExpr(ObjCIvarDecl *d, QualType t,
529 SourceLocation l, SourceLocation oploc,
531 bool arrow = false, bool freeIvar = false)
532 : Expr(ObjCIvarRefExprClass, t, VK_LValue,
533 d->isBitField() ? OK_BitField : OK_Ordinary,
534 /*TypeDependent=*/false, base->isValueDependent(),
535 base->isInstantiationDependent(),
536 base->containsUnexpandedParameterPack()),
537 D(d), Base(base), Loc(l), OpLoc(oploc), IsArrow(arrow),
538 IsFreeIvar(freeIvar) {}
540 explicit ObjCIvarRefExpr(EmptyShell Empty)
541 : Expr(ObjCIvarRefExprClass, Empty) {}
543 ObjCIvarDecl *getDecl() { return D; }
544 const ObjCIvarDecl *getDecl() const { return D; }
545 void setDecl(ObjCIvarDecl *d) { D = d; }
547 const Expr *getBase() const { return cast<Expr>(Base); }
548 Expr *getBase() { return cast<Expr>(Base); }
549 void setBase(Expr * base) { Base = base; }
551 bool isArrow() const { return IsArrow; }
552 bool isFreeIvar() const { return IsFreeIvar; }
553 void setIsArrow(bool A) { IsArrow = A; }
554 void setIsFreeIvar(bool A) { IsFreeIvar = A; }
556 SourceLocation getLocation() const { return Loc; }
557 void setLocation(SourceLocation L) { Loc = L; }
559 SourceLocation getLocStart() const LLVM_READONLY {
560 return isFreeIvar() ? Loc : getBase()->getLocStart();
562 SourceLocation getLocEnd() const LLVM_READONLY { return Loc; }
564 SourceLocation getOpLoc() const { return OpLoc; }
565 void setOpLoc(SourceLocation L) { OpLoc = L; }
568 child_range children() { return child_range(&Base, &Base+1); }
570 static bool classof(const Stmt *T) {
571 return T->getStmtClass() == ObjCIvarRefExprClass;
575 /// ObjCPropertyRefExpr - A dot-syntax expression to access an ObjC
577 class ObjCPropertyRefExpr : public Expr {
579 /// If the bool is true, this is an implicit property reference; the
580 /// pointer is an (optional) ObjCMethodDecl and Setter may be set.
581 /// if the bool is false, this is an explicit property reference;
582 /// the pointer is an ObjCPropertyDecl and Setter is always null.
583 llvm::PointerIntPair<NamedDecl *, 1, bool> PropertyOrGetter;
585 /// \brief Indicates whether the property reference will result in a message
586 /// to the getter, the setter, or both.
587 /// This applies to both implicit and explicit property references.
588 enum MethodRefFlags {
590 MethodRef_Getter = 0x1,
591 MethodRef_Setter = 0x2
594 /// \brief Contains the Setter method pointer and MethodRefFlags bit flags.
595 llvm::PointerIntPair<ObjCMethodDecl *, 2, unsigned> SetterAndMethodRefFlags;
597 // FIXME: Maybe we should store the property identifier here,
598 // because it's not rederivable from the other data when there's an
599 // implicit property with no getter (because the 'foo' -> 'setFoo:'
600 // transformation is lossy on the first character).
602 SourceLocation IdLoc;
604 /// \brief When the receiver in property access is 'super', this is
605 /// the location of the 'super' keyword. When it's an interface,
606 /// this is that interface.
607 SourceLocation ReceiverLoc;
608 llvm::PointerUnion3<Stmt *, const Type *, ObjCInterfaceDecl *> Receiver;
611 ObjCPropertyRefExpr(ObjCPropertyDecl *PD, QualType t,
612 ExprValueKind VK, ExprObjectKind OK,
613 SourceLocation l, Expr *base)
614 : Expr(ObjCPropertyRefExprClass, t, VK, OK,
615 /*TypeDependent=*/false, base->isValueDependent(),
616 base->isInstantiationDependent(),
617 base->containsUnexpandedParameterPack()),
618 PropertyOrGetter(PD, false), IdLoc(l), Receiver(base) {
619 assert(t->isSpecificPlaceholderType(BuiltinType::PseudoObject));
622 ObjCPropertyRefExpr(ObjCPropertyDecl *PD, QualType t,
623 ExprValueKind VK, ExprObjectKind OK,
624 SourceLocation l, SourceLocation sl, QualType st)
625 : Expr(ObjCPropertyRefExprClass, t, VK, OK,
626 /*TypeDependent=*/false, false, st->isInstantiationDependentType(),
627 st->containsUnexpandedParameterPack()),
628 PropertyOrGetter(PD, false), IdLoc(l), ReceiverLoc(sl),
629 Receiver(st.getTypePtr()) {
630 assert(t->isSpecificPlaceholderType(BuiltinType::PseudoObject));
633 ObjCPropertyRefExpr(ObjCMethodDecl *Getter, ObjCMethodDecl *Setter,
634 QualType T, ExprValueKind VK, ExprObjectKind OK,
635 SourceLocation IdLoc, Expr *Base)
636 : Expr(ObjCPropertyRefExprClass, T, VK, OK, false,
637 Base->isValueDependent(), Base->isInstantiationDependent(),
638 Base->containsUnexpandedParameterPack()),
639 PropertyOrGetter(Getter, true), SetterAndMethodRefFlags(Setter, 0),
640 IdLoc(IdLoc), Receiver(Base) {
641 assert(T->isSpecificPlaceholderType(BuiltinType::PseudoObject));
644 ObjCPropertyRefExpr(ObjCMethodDecl *Getter, ObjCMethodDecl *Setter,
645 QualType T, ExprValueKind VK, ExprObjectKind OK,
646 SourceLocation IdLoc,
647 SourceLocation SuperLoc, QualType SuperTy)
648 : Expr(ObjCPropertyRefExprClass, T, VK, OK, false, false, false, false),
649 PropertyOrGetter(Getter, true), SetterAndMethodRefFlags(Setter, 0),
650 IdLoc(IdLoc), ReceiverLoc(SuperLoc), Receiver(SuperTy.getTypePtr()) {
651 assert(T->isSpecificPlaceholderType(BuiltinType::PseudoObject));
654 ObjCPropertyRefExpr(ObjCMethodDecl *Getter, ObjCMethodDecl *Setter,
655 QualType T, ExprValueKind VK, ExprObjectKind OK,
656 SourceLocation IdLoc,
657 SourceLocation ReceiverLoc, ObjCInterfaceDecl *Receiver)
658 : Expr(ObjCPropertyRefExprClass, T, VK, OK, false, false, false, false),
659 PropertyOrGetter(Getter, true), SetterAndMethodRefFlags(Setter, 0),
660 IdLoc(IdLoc), ReceiverLoc(ReceiverLoc), Receiver(Receiver) {
661 assert(T->isSpecificPlaceholderType(BuiltinType::PseudoObject));
664 explicit ObjCPropertyRefExpr(EmptyShell Empty)
665 : Expr(ObjCPropertyRefExprClass, Empty) {}
667 bool isImplicitProperty() const { return PropertyOrGetter.getInt(); }
668 bool isExplicitProperty() const { return !PropertyOrGetter.getInt(); }
670 ObjCPropertyDecl *getExplicitProperty() const {
671 assert(!isImplicitProperty());
672 return cast<ObjCPropertyDecl>(PropertyOrGetter.getPointer());
675 ObjCMethodDecl *getImplicitPropertyGetter() const {
676 assert(isImplicitProperty());
677 return cast_or_null<ObjCMethodDecl>(PropertyOrGetter.getPointer());
680 ObjCMethodDecl *getImplicitPropertySetter() const {
681 assert(isImplicitProperty());
682 return SetterAndMethodRefFlags.getPointer();
685 Selector getGetterSelector() const {
686 if (isImplicitProperty())
687 return getImplicitPropertyGetter()->getSelector();
688 return getExplicitProperty()->getGetterName();
691 Selector getSetterSelector() const {
692 if (isImplicitProperty())
693 return getImplicitPropertySetter()->getSelector();
694 return getExplicitProperty()->getSetterName();
697 /// \brief True if the property reference will result in a message to the
699 /// This applies to both implicit and explicit property references.
700 bool isMessagingGetter() const {
701 return SetterAndMethodRefFlags.getInt() & MethodRef_Getter;
704 /// \brief True if the property reference will result in a message to the
706 /// This applies to both implicit and explicit property references.
707 bool isMessagingSetter() const {
708 return SetterAndMethodRefFlags.getInt() & MethodRef_Setter;
711 void setIsMessagingGetter(bool val = true) {
712 setMethodRefFlag(MethodRef_Getter, val);
715 void setIsMessagingSetter(bool val = true) {
716 setMethodRefFlag(MethodRef_Setter, val);
719 const Expr *getBase() const {
720 return cast<Expr>(Receiver.get<Stmt*>());
723 return cast<Expr>(Receiver.get<Stmt*>());
726 SourceLocation getLocation() const { return IdLoc; }
728 SourceLocation getReceiverLocation() const { return ReceiverLoc; }
730 QualType getSuperReceiverType() const {
731 return QualType(Receiver.get<const Type*>(), 0);
734 ObjCInterfaceDecl *getClassReceiver() const {
735 return Receiver.get<ObjCInterfaceDecl*>();
738 bool isObjectReceiver() const { return Receiver.is<Stmt*>(); }
739 bool isSuperReceiver() const { return Receiver.is<const Type*>(); }
740 bool isClassReceiver() const { return Receiver.is<ObjCInterfaceDecl*>(); }
742 /// Determine the type of the base, regardless of the kind of receiver.
743 QualType getReceiverType(const ASTContext &ctx) const;
745 SourceLocation getLocStart() const LLVM_READONLY {
746 return isObjectReceiver() ? getBase()->getLocStart() :getReceiverLocation();
749 SourceLocation getLocEnd() const LLVM_READONLY { return IdLoc; }
752 child_range children() {
753 if (Receiver.is<Stmt*>()) {
754 Stmt **begin = reinterpret_cast<Stmt**>(&Receiver); // hack!
755 return child_range(begin, begin+1);
757 return child_range(child_iterator(), child_iterator());
760 static bool classof(const Stmt *T) {
761 return T->getStmtClass() == ObjCPropertyRefExprClass;
765 friend class ASTStmtReader;
766 friend class ASTStmtWriter;
768 void setExplicitProperty(ObjCPropertyDecl *D, unsigned methRefFlags) {
769 PropertyOrGetter.setPointer(D);
770 PropertyOrGetter.setInt(false);
771 SetterAndMethodRefFlags.setPointer(nullptr);
772 SetterAndMethodRefFlags.setInt(methRefFlags);
775 void setImplicitProperty(ObjCMethodDecl *Getter, ObjCMethodDecl *Setter,
776 unsigned methRefFlags) {
777 PropertyOrGetter.setPointer(Getter);
778 PropertyOrGetter.setInt(true);
779 SetterAndMethodRefFlags.setPointer(Setter);
780 SetterAndMethodRefFlags.setInt(methRefFlags);
783 void setBase(Expr *Base) { Receiver = Base; }
784 void setSuperReceiver(QualType T) { Receiver = T.getTypePtr(); }
785 void setClassReceiver(ObjCInterfaceDecl *D) { Receiver = D; }
787 void setLocation(SourceLocation L) { IdLoc = L; }
788 void setReceiverLocation(SourceLocation Loc) { ReceiverLoc = Loc; }
790 void setMethodRefFlag(MethodRefFlags flag, bool val) {
791 unsigned f = SetterAndMethodRefFlags.getInt();
796 SetterAndMethodRefFlags.setInt(f);
800 /// ObjCSubscriptRefExpr - used for array and dictionary subscripting.
801 /// array[4] = array[3]; dictionary[key] = dictionary[alt_key];
802 class ObjCSubscriptRefExpr : public Expr {
803 // Location of ']' in an indexing expression.
804 SourceLocation RBracket;
806 // array/dictionary base expression.
807 // for arrays, this is a numeric expression. For dictionaries, this is
808 // an objective-c object pointer expression.
809 enum { BASE, KEY, END_EXPR };
810 Stmt* SubExprs[END_EXPR];
812 ObjCMethodDecl *GetAtIndexMethodDecl;
814 // For immutable objects this is null. When ObjCSubscriptRefExpr is to read
815 // an indexed object this is null too.
816 ObjCMethodDecl *SetAtIndexMethodDecl;
819 ObjCSubscriptRefExpr(Expr *base, Expr *key, QualType T,
820 ExprValueKind VK, ExprObjectKind OK,
821 ObjCMethodDecl *getMethod,
822 ObjCMethodDecl *setMethod, SourceLocation RB)
823 : Expr(ObjCSubscriptRefExprClass, T, VK, OK,
824 base->isTypeDependent() || key->isTypeDependent(),
825 base->isValueDependent() || key->isValueDependent(),
826 (base->isInstantiationDependent() ||
827 key->isInstantiationDependent()),
828 (base->containsUnexpandedParameterPack() ||
829 key->containsUnexpandedParameterPack())),
830 RBracket(RB), GetAtIndexMethodDecl(getMethod),
831 SetAtIndexMethodDecl(setMethod) {
832 SubExprs[BASE] = base; SubExprs[KEY] = key;
835 explicit ObjCSubscriptRefExpr(EmptyShell Empty)
836 : Expr(ObjCSubscriptRefExprClass, Empty) {}
838 SourceLocation getRBracket() const { return RBracket; }
839 void setRBracket(SourceLocation RB) { RBracket = RB; }
841 SourceLocation getLocStart() const LLVM_READONLY {
842 return SubExprs[BASE]->getLocStart();
845 SourceLocation getLocEnd() const LLVM_READONLY { return RBracket; }
847 Expr *getBaseExpr() const { return cast<Expr>(SubExprs[BASE]); }
848 void setBaseExpr(Stmt *S) { SubExprs[BASE] = S; }
850 Expr *getKeyExpr() const { return cast<Expr>(SubExprs[KEY]); }
851 void setKeyExpr(Stmt *S) { SubExprs[KEY] = S; }
853 ObjCMethodDecl *getAtIndexMethodDecl() const {
854 return GetAtIndexMethodDecl;
857 ObjCMethodDecl *setAtIndexMethodDecl() const {
858 return SetAtIndexMethodDecl;
861 bool isArraySubscriptRefExpr() const {
862 return getKeyExpr()->getType()->isIntegralOrEnumerationType();
865 child_range children() {
866 return child_range(SubExprs, SubExprs+END_EXPR);
869 static bool classof(const Stmt *T) {
870 return T->getStmtClass() == ObjCSubscriptRefExprClass;
874 friend class ASTStmtReader;
877 /// \brief An expression that sends a message to the given Objective-C
880 /// The following contains two message send expressions:
883 /// [[NSString alloc] initWithString:@"Hello"]
886 /// The innermost message send invokes the "alloc" class method on the
887 /// NSString class, while the outermost message send invokes the
888 /// "initWithString" instance method on the object returned from
889 /// NSString's "alloc". In all, an Objective-C message send can take
890 /// on four different (although related) forms:
892 /// 1. Send to an object instance.
893 /// 2. Send to a class.
894 /// 3. Send to the superclass instance of the current class.
895 /// 4. Send to the superclass of the current class.
897 /// All four kinds of message sends are modeled by the ObjCMessageExpr
898 /// class, and can be distinguished via \c getReceiverKind(). Example:
900 /// The "void *" trailing objects are actually ONE void * (the
901 /// receiver pointer), and NumArgs Expr *. But due to the
902 /// implementation of children(), these must be together contiguously.
903 class ObjCMessageExpr final
905 private llvm::TrailingObjects<ObjCMessageExpr, void *, SourceLocation> {
906 /// \brief Stores either the selector that this message is sending
907 /// to (when \c HasMethod is zero) or an \c ObjCMethodDecl pointer
908 /// referring to the method that we type-checked against.
909 uintptr_t SelectorOrMethod = 0;
911 enum { NumArgsBitWidth = 16 };
913 /// \brief The number of arguments in the message send, not
914 /// including the receiver.
915 unsigned NumArgs : NumArgsBitWidth;
917 /// \brief The kind of message send this is, which is one of the
918 /// ReceiverKind values.
920 /// We pad this out to a byte to avoid excessive masking and shifting.
923 /// \brief Whether we have an actual method prototype in \c
924 /// SelectorOrMethod.
926 /// When non-zero, we have a method declaration; otherwise, we just
928 unsigned HasMethod : 1;
930 /// \brief Whether this message send is a "delegate init call",
931 /// i.e. a call of an init method on self from within an init method.
932 unsigned IsDelegateInitCall : 1;
934 /// \brief Whether this message send was implicitly generated by
935 /// the implementation rather than explicitly written by the user.
936 unsigned IsImplicit : 1;
938 /// \brief Whether the locations of the selector identifiers are in a
939 /// "standard" position, a enum SelectorLocationsKind.
940 unsigned SelLocsKind : 2;
942 /// \brief When the message expression is a send to 'super', this is
943 /// the location of the 'super' keyword.
944 SourceLocation SuperLoc;
946 /// \brief The source locations of the open and close square
947 /// brackets ('[' and ']', respectively).
948 SourceLocation LBracLoc, RBracLoc;
950 ObjCMessageExpr(EmptyShell Empty, unsigned NumArgs)
951 : Expr(ObjCMessageExprClass, Empty), Kind(0), HasMethod(false),
952 IsDelegateInitCall(false), IsImplicit(false), SelLocsKind(0) {
956 ObjCMessageExpr(QualType T, ExprValueKind VK,
957 SourceLocation LBracLoc,
958 SourceLocation SuperLoc,
959 bool IsInstanceSuper,
962 ArrayRef<SourceLocation> SelLocs,
963 SelectorLocationsKind SelLocsK,
964 ObjCMethodDecl *Method,
965 ArrayRef<Expr *> Args,
966 SourceLocation RBracLoc,
968 ObjCMessageExpr(QualType T, ExprValueKind VK,
969 SourceLocation LBracLoc,
970 TypeSourceInfo *Receiver,
972 ArrayRef<SourceLocation> SelLocs,
973 SelectorLocationsKind SelLocsK,
974 ObjCMethodDecl *Method,
975 ArrayRef<Expr *> Args,
976 SourceLocation RBracLoc,
978 ObjCMessageExpr(QualType T, ExprValueKind VK,
979 SourceLocation LBracLoc,
982 ArrayRef<SourceLocation> SelLocs,
983 SelectorLocationsKind SelLocsK,
984 ObjCMethodDecl *Method,
985 ArrayRef<Expr *> Args,
986 SourceLocation RBracLoc,
989 size_t numTrailingObjects(OverloadToken<void *>) const { return NumArgs + 1; }
991 void setNumArgs(unsigned Num) {
992 assert((Num >> NumArgsBitWidth) == 0 && "Num of args is out of range!");
996 void initArgsAndSelLocs(ArrayRef<Expr *> Args,
997 ArrayRef<SourceLocation> SelLocs,
998 SelectorLocationsKind SelLocsK);
1000 /// \brief Retrieve the pointer value of the message receiver.
1001 void *getReceiverPointer() const { return *getTrailingObjects<void *>(); }
1003 /// \brief Set the pointer value of the message receiver.
1004 void setReceiverPointer(void *Value) {
1005 *getTrailingObjects<void *>() = Value;
1008 SelectorLocationsKind getSelLocsKind() const {
1009 return (SelectorLocationsKind)SelLocsKind;
1012 bool hasStandardSelLocs() const {
1013 return getSelLocsKind() != SelLoc_NonStandard;
1016 /// \brief Get a pointer to the stored selector identifiers locations array.
1017 /// No locations will be stored if HasStandardSelLocs is true.
1018 SourceLocation *getStoredSelLocs() {
1019 return getTrailingObjects<SourceLocation>();
1021 const SourceLocation *getStoredSelLocs() const {
1022 return getTrailingObjects<SourceLocation>();
1025 /// \brief Get the number of stored selector identifiers locations.
1026 /// No locations will be stored if HasStandardSelLocs is true.
1027 unsigned getNumStoredSelLocs() const {
1028 if (hasStandardSelLocs())
1030 return getNumSelectorLocs();
1033 static ObjCMessageExpr *alloc(const ASTContext &C,
1034 ArrayRef<Expr *> Args,
1035 SourceLocation RBraceLoc,
1036 ArrayRef<SourceLocation> SelLocs,
1038 SelectorLocationsKind &SelLocsK);
1039 static ObjCMessageExpr *alloc(const ASTContext &C,
1041 unsigned NumStoredSelLocs);
1044 friend class ASTStmtReader;
1045 friend class ASTStmtWriter;
1046 friend TrailingObjects;
1048 /// \brief The kind of receiver this message is sending to.
1050 /// \brief The receiver is a class.
1053 /// \brief The receiver is an object instance.
1056 /// \brief The receiver is a superclass.
1059 /// \brief The receiver is the instance of the superclass object.
1063 /// \brief Create a message send to super.
1065 /// \param Context The ASTContext in which this expression will be created.
1067 /// \param T The result type of this message.
1069 /// \param VK The value kind of this message. A message returning
1070 /// a l-value or r-value reference will be an l-value or x-value,
1073 /// \param LBracLoc The location of the open square bracket '['.
1075 /// \param SuperLoc The location of the "super" keyword.
1077 /// \param IsInstanceSuper Whether this is an instance "super"
1078 /// message (otherwise, it's a class "super" message).
1080 /// \param Sel The selector used to determine which method gets called.
1082 /// \param Method The Objective-C method against which this message
1083 /// send was type-checked. May be nullptr.
1085 /// \param Args The message send arguments.
1087 /// \param RBracLoc The location of the closing square bracket ']'.
1088 static ObjCMessageExpr *Create(const ASTContext &Context, QualType T,
1090 SourceLocation LBracLoc,
1091 SourceLocation SuperLoc,
1092 bool IsInstanceSuper,
1095 ArrayRef<SourceLocation> SelLocs,
1096 ObjCMethodDecl *Method,
1097 ArrayRef<Expr *> Args,
1098 SourceLocation RBracLoc,
1101 /// \brief Create a class message send.
1103 /// \param Context The ASTContext in which this expression will be created.
1105 /// \param T The result type of this message.
1107 /// \param VK The value kind of this message. A message returning
1108 /// a l-value or r-value reference will be an l-value or x-value,
1111 /// \param LBracLoc The location of the open square bracket '['.
1113 /// \param Receiver The type of the receiver, including
1114 /// source-location information.
1116 /// \param Sel The selector used to determine which method gets called.
1118 /// \param Method The Objective-C method against which this message
1119 /// send was type-checked. May be nullptr.
1121 /// \param Args The message send arguments.
1123 /// \param RBracLoc The location of the closing square bracket ']'.
1124 static ObjCMessageExpr *Create(const ASTContext &Context, QualType T,
1126 SourceLocation LBracLoc,
1127 TypeSourceInfo *Receiver,
1129 ArrayRef<SourceLocation> SelLocs,
1130 ObjCMethodDecl *Method,
1131 ArrayRef<Expr *> Args,
1132 SourceLocation RBracLoc,
1135 /// \brief Create an instance message send.
1137 /// \param Context The ASTContext in which this expression will be created.
1139 /// \param T The result type of this message.
1141 /// \param VK The value kind of this message. A message returning
1142 /// a l-value or r-value reference will be an l-value or x-value,
1145 /// \param LBracLoc The location of the open square bracket '['.
1147 /// \param Receiver The expression used to produce the object that
1148 /// will receive this message.
1150 /// \param Sel The selector used to determine which method gets called.
1152 /// \param Method The Objective-C method against which this message
1153 /// send was type-checked. May be nullptr.
1155 /// \param Args The message send arguments.
1157 /// \param RBracLoc The location of the closing square bracket ']'.
1158 static ObjCMessageExpr *Create(const ASTContext &Context, QualType T,
1160 SourceLocation LBracLoc,
1163 ArrayRef<SourceLocation> SeLocs,
1164 ObjCMethodDecl *Method,
1165 ArrayRef<Expr *> Args,
1166 SourceLocation RBracLoc,
1169 /// \brief Create an empty Objective-C message expression, to be
1170 /// filled in by subsequent calls.
1172 /// \param Context The context in which the message send will be created.
1174 /// \param NumArgs The number of message arguments, not including
1176 static ObjCMessageExpr *CreateEmpty(const ASTContext &Context,
1178 unsigned NumStoredSelLocs);
1180 /// \brief Indicates whether the message send was implicitly
1181 /// generated by the implementation. If false, it was written explicitly
1182 /// in the source code.
1183 bool isImplicit() const { return IsImplicit; }
1185 /// \brief Determine the kind of receiver that this message is being
1187 ReceiverKind getReceiverKind() const { return (ReceiverKind)Kind; }
1189 /// \brief Source range of the receiver.
1190 SourceRange getReceiverRange() const;
1192 /// \brief Determine whether this is an instance message to either a
1193 /// computed object or to super.
1194 bool isInstanceMessage() const {
1195 return getReceiverKind() == Instance || getReceiverKind() == SuperInstance;
1198 /// \brief Determine whether this is an class message to either a
1199 /// specified class or to super.
1200 bool isClassMessage() const {
1201 return getReceiverKind() == Class || getReceiverKind() == SuperClass;
1204 /// \brief Returns the object expression (receiver) for an instance message,
1205 /// or null for a message that is not an instance message.
1206 Expr *getInstanceReceiver() {
1207 if (getReceiverKind() == Instance)
1208 return static_cast<Expr *>(getReceiverPointer());
1212 const Expr *getInstanceReceiver() const {
1213 return const_cast<ObjCMessageExpr*>(this)->getInstanceReceiver();
1216 /// \brief Turn this message send into an instance message that
1217 /// computes the receiver object with the given expression.
1218 void setInstanceReceiver(Expr *rec) {
1220 setReceiverPointer(rec);
1223 /// \brief Returns the type of a class message send, or NULL if the
1224 /// message is not a class message.
1225 QualType getClassReceiver() const {
1226 if (TypeSourceInfo *TSInfo = getClassReceiverTypeInfo())
1227 return TSInfo->getType();
1232 /// \brief Returns a type-source information of a class message
1233 /// send, or nullptr if the message is not a class message.
1234 TypeSourceInfo *getClassReceiverTypeInfo() const {
1235 if (getReceiverKind() == Class)
1236 return reinterpret_cast<TypeSourceInfo *>(getReceiverPointer());
1240 void setClassReceiver(TypeSourceInfo *TSInfo) {
1242 setReceiverPointer(TSInfo);
1245 /// \brief Retrieve the location of the 'super' keyword for a class
1246 /// or instance message to 'super', otherwise an invalid source location.
1247 SourceLocation getSuperLoc() const {
1248 if (getReceiverKind() == SuperInstance || getReceiverKind() == SuperClass)
1251 return SourceLocation();
1254 /// \brief Retrieve the receiver type to which this message is being directed.
1256 /// This routine cross-cuts all of the different kinds of message
1257 /// sends to determine what the underlying (statically known) type
1258 /// of the receiver will be; use \c getReceiverKind() to determine
1259 /// whether the message is a class or an instance method, whether it
1260 /// is a send to super or not, etc.
1262 /// \returns The type of the receiver.
1263 QualType getReceiverType() const;
1265 /// \brief Retrieve the Objective-C interface to which this message
1266 /// is being directed, if known.
1268 /// This routine cross-cuts all of the different kinds of message
1269 /// sends to determine what the underlying (statically known) type
1270 /// of the receiver will be; use \c getReceiverKind() to determine
1271 /// whether the message is a class or an instance method, whether it
1272 /// is a send to super or not, etc.
1274 /// \returns The Objective-C interface if known, otherwise nullptr.
1275 ObjCInterfaceDecl *getReceiverInterface() const;
1277 /// \brief Retrieve the type referred to by 'super'.
1279 /// The returned type will either be an ObjCInterfaceType (for an
1280 /// class message to super) or an ObjCObjectPointerType that refers
1281 /// to a class (for an instance message to super);
1282 QualType getSuperType() const {
1283 if (getReceiverKind() == SuperInstance || getReceiverKind() == SuperClass)
1284 return QualType::getFromOpaquePtr(getReceiverPointer());
1289 void setSuper(SourceLocation Loc, QualType T, bool IsInstanceSuper) {
1290 Kind = IsInstanceSuper? SuperInstance : SuperClass;
1292 setReceiverPointer(T.getAsOpaquePtr());
1295 Selector getSelector() const;
1297 void setSelector(Selector S) {
1299 SelectorOrMethod = reinterpret_cast<uintptr_t>(S.getAsOpaquePtr());
1302 const ObjCMethodDecl *getMethodDecl() const {
1304 return reinterpret_cast<const ObjCMethodDecl *>(SelectorOrMethod);
1309 ObjCMethodDecl *getMethodDecl() {
1311 return reinterpret_cast<ObjCMethodDecl *>(SelectorOrMethod);
1316 void setMethodDecl(ObjCMethodDecl *MD) {
1318 SelectorOrMethod = reinterpret_cast<uintptr_t>(MD);
1321 ObjCMethodFamily getMethodFamily() const {
1322 if (HasMethod) return getMethodDecl()->getMethodFamily();
1323 return getSelector().getMethodFamily();
1326 /// \brief Return the number of actual arguments in this message,
1327 /// not counting the receiver.
1328 unsigned getNumArgs() const { return NumArgs; }
1330 /// \brief Retrieve the arguments to this message, not including the
1333 return reinterpret_cast<Expr **>(getTrailingObjects<void *>() + 1);
1335 const Expr * const *getArgs() const {
1336 return reinterpret_cast<const Expr *const *>(getTrailingObjects<void *>() +
1340 /// getArg - Return the specified argument.
1341 Expr *getArg(unsigned Arg) {
1342 assert(Arg < NumArgs && "Arg access out of range!");
1343 return getArgs()[Arg];
1345 const Expr *getArg(unsigned Arg) const {
1346 assert(Arg < NumArgs && "Arg access out of range!");
1347 return getArgs()[Arg];
1350 /// setArg - Set the specified argument.
1351 void setArg(unsigned Arg, Expr *ArgExpr) {
1352 assert(Arg < NumArgs && "Arg access out of range!");
1353 getArgs()[Arg] = ArgExpr;
1356 /// isDelegateInitCall - Answers whether this message send has been
1357 /// tagged as a "delegate init call", i.e. a call to a method in the
1358 /// -init family on self from within an -init method implementation.
1359 bool isDelegateInitCall() const { return IsDelegateInitCall; }
1360 void setDelegateInitCall(bool isDelegate) { IsDelegateInitCall = isDelegate; }
1362 SourceLocation getLeftLoc() const { return LBracLoc; }
1363 SourceLocation getRightLoc() const { return RBracLoc; }
1365 SourceLocation getSelectorStartLoc() const {
1367 return getLocStart();
1368 return getSelectorLoc(0);
1371 SourceLocation getSelectorLoc(unsigned Index) const {
1372 assert(Index < getNumSelectorLocs() && "Index out of range!");
1373 if (hasStandardSelLocs())
1374 return getStandardSelectorLoc(Index, getSelector(),
1375 getSelLocsKind() == SelLoc_StandardWithSpace,
1376 llvm::makeArrayRef(const_cast<Expr**>(getArgs()),
1379 return getStoredSelLocs()[Index];
1382 void getSelectorLocs(SmallVectorImpl<SourceLocation> &SelLocs) const;
1384 unsigned getNumSelectorLocs() const {
1387 Selector Sel = getSelector();
1388 if (Sel.isUnarySelector())
1390 return Sel.getNumArgs();
1393 void setSourceRange(SourceRange R) {
1394 LBracLoc = R.getBegin();
1395 RBracLoc = R.getEnd();
1398 SourceLocation getLocStart() const LLVM_READONLY { return LBracLoc; }
1399 SourceLocation getLocEnd() const LLVM_READONLY { return RBracLoc; }
1402 child_range children();
1404 using arg_iterator = ExprIterator;
1405 using const_arg_iterator = ConstExprIterator;
1407 llvm::iterator_range<arg_iterator> arguments() {
1408 return llvm::make_range(arg_begin(), arg_end());
1411 llvm::iterator_range<const_arg_iterator> arguments() const {
1412 return llvm::make_range(arg_begin(), arg_end());
1415 arg_iterator arg_begin() { return reinterpret_cast<Stmt **>(getArgs()); }
1417 arg_iterator arg_end() {
1418 return reinterpret_cast<Stmt **>(getArgs() + NumArgs);
1421 const_arg_iterator arg_begin() const {
1422 return reinterpret_cast<Stmt const * const*>(getArgs());
1425 const_arg_iterator arg_end() const {
1426 return reinterpret_cast<Stmt const * const*>(getArgs() + NumArgs);
1429 static bool classof(const Stmt *T) {
1430 return T->getStmtClass() == ObjCMessageExprClass;
1434 /// ObjCIsaExpr - Represent X->isa and X.isa when X is an ObjC 'id' type.
1435 /// (similar in spirit to MemberExpr).
1436 class ObjCIsaExpr : public Expr {
1437 /// Base - the expression for the base object pointer.
1440 /// IsaMemberLoc - This is the location of the 'isa'.
1441 SourceLocation IsaMemberLoc;
1443 /// OpLoc - This is the location of '.' or '->'
1444 SourceLocation OpLoc;
1446 /// IsArrow - True if this is "X->F", false if this is "X.F".
1450 ObjCIsaExpr(Expr *base, bool isarrow, SourceLocation l, SourceLocation oploc,
1452 : Expr(ObjCIsaExprClass, ty, VK_LValue, OK_Ordinary,
1453 /*TypeDependent=*/false, base->isValueDependent(),
1454 base->isInstantiationDependent(),
1455 /*ContainsUnexpandedParameterPack=*/false),
1456 Base(base), IsaMemberLoc(l), OpLoc(oploc), IsArrow(isarrow) {}
1458 /// \brief Build an empty expression.
1459 explicit ObjCIsaExpr(EmptyShell Empty) : Expr(ObjCIsaExprClass, Empty) {}
1461 void setBase(Expr *E) { Base = E; }
1462 Expr *getBase() const { return cast<Expr>(Base); }
1464 bool isArrow() const { return IsArrow; }
1465 void setArrow(bool A) { IsArrow = A; }
1467 /// getMemberLoc - Return the location of the "member", in X->F, it is the
1468 /// location of 'F'.
1469 SourceLocation getIsaMemberLoc() const { return IsaMemberLoc; }
1470 void setIsaMemberLoc(SourceLocation L) { IsaMemberLoc = L; }
1472 SourceLocation getOpLoc() const { return OpLoc; }
1473 void setOpLoc(SourceLocation L) { OpLoc = L; }
1475 SourceLocation getLocStart() const LLVM_READONLY {
1476 return getBase()->getLocStart();
1479 SourceLocation getBaseLocEnd() const LLVM_READONLY {
1480 return getBase()->getLocEnd();
1483 SourceLocation getLocEnd() const LLVM_READONLY { return IsaMemberLoc; }
1485 SourceLocation getExprLoc() const LLVM_READONLY { return IsaMemberLoc; }
1488 child_range children() { return child_range(&Base, &Base+1); }
1490 static bool classof(const Stmt *T) {
1491 return T->getStmtClass() == ObjCIsaExprClass;
1495 /// ObjCIndirectCopyRestoreExpr - Represents the passing of a function
1496 /// argument by indirect copy-restore in ARC. This is used to support
1497 /// passing indirect arguments with the wrong lifetime, e.g. when
1498 /// passing the address of a __strong local variable to an 'out'
1499 /// parameter. This expression kind is only valid in an "argument"
1500 /// position to some sort of call expression.
1502 /// The parameter must have type 'pointer to T', and the argument must
1503 /// have type 'pointer to U', where T and U agree except possibly in
1504 /// qualification. If the argument value is null, then a null pointer
1505 /// is passed; otherwise it points to an object A, and:
1506 /// 1. A temporary object B of type T is initialized, either by
1507 /// zero-initialization (used when initializing an 'out' parameter)
1508 /// or copy-initialization (used when initializing an 'inout'
1510 /// 2. The address of the temporary is passed to the function.
1511 /// 3. If the call completes normally, A is move-assigned from B.
1512 /// 4. Finally, A is destroyed immediately.
1514 /// Currently 'T' must be a retainable object lifetime and must be
1515 /// __autoreleasing; this qualifier is ignored when initializing
1517 class ObjCIndirectCopyRestoreExpr : public Expr {
1518 friend class ASTReader;
1519 friend class ASTStmtReader;
1523 // unsigned ObjCIndirectCopyRestoreBits.ShouldCopy : 1;
1525 explicit ObjCIndirectCopyRestoreExpr(EmptyShell Empty)
1526 : Expr(ObjCIndirectCopyRestoreExprClass, Empty) {}
1528 void setShouldCopy(bool shouldCopy) {
1529 ObjCIndirectCopyRestoreExprBits.ShouldCopy = shouldCopy;
1533 ObjCIndirectCopyRestoreExpr(Expr *operand, QualType type, bool shouldCopy)
1534 : Expr(ObjCIndirectCopyRestoreExprClass, type, VK_LValue, OK_Ordinary,
1535 operand->isTypeDependent(), operand->isValueDependent(),
1536 operand->isInstantiationDependent(),
1537 operand->containsUnexpandedParameterPack()),
1539 setShouldCopy(shouldCopy);
1542 Expr *getSubExpr() { return cast<Expr>(Operand); }
1543 const Expr *getSubExpr() const { return cast<Expr>(Operand); }
1545 /// shouldCopy - True if we should do the 'copy' part of the
1546 /// copy-restore. If false, the temporary will be zero-initialized.
1547 bool shouldCopy() const { return ObjCIndirectCopyRestoreExprBits.ShouldCopy; }
1549 child_range children() { return child_range(&Operand, &Operand+1); }
1551 // Source locations are determined by the subexpression.
1552 SourceLocation getLocStart() const LLVM_READONLY {
1553 return Operand->getLocStart();
1555 SourceLocation getLocEnd() const LLVM_READONLY { return Operand->getLocEnd();}
1557 SourceLocation getExprLoc() const LLVM_READONLY {
1558 return getSubExpr()->getExprLoc();
1561 static bool classof(const Stmt *s) {
1562 return s->getStmtClass() == ObjCIndirectCopyRestoreExprClass;
1566 /// \brief An Objective-C "bridged" cast expression, which casts between
1567 /// Objective-C pointers and C pointers, transferring ownership in the process.
1570 /// NSString *str = (__bridge_transfer NSString *)CFCreateString();
1572 class ObjCBridgedCastExpr final
1573 : public ExplicitCastExpr,
1574 private llvm::TrailingObjects<ObjCBridgedCastExpr, CXXBaseSpecifier *> {
1575 friend class ASTStmtReader;
1576 friend class ASTStmtWriter;
1577 friend class CastExpr;
1578 friend TrailingObjects;
1580 SourceLocation LParenLoc;
1581 SourceLocation BridgeKeywordLoc;
1585 ObjCBridgedCastExpr(SourceLocation LParenLoc, ObjCBridgeCastKind Kind,
1586 CastKind CK, SourceLocation BridgeKeywordLoc,
1587 TypeSourceInfo *TSInfo, Expr *Operand)
1588 : ExplicitCastExpr(ObjCBridgedCastExprClass, TSInfo->getType(), VK_RValue,
1589 CK, Operand, 0, TSInfo),
1590 LParenLoc(LParenLoc), BridgeKeywordLoc(BridgeKeywordLoc), Kind(Kind) {}
1592 /// \brief Construct an empty Objective-C bridged cast.
1593 explicit ObjCBridgedCastExpr(EmptyShell Shell)
1594 : ExplicitCastExpr(ObjCBridgedCastExprClass, Shell, 0) {}
1596 SourceLocation getLParenLoc() const { return LParenLoc; }
1598 /// \brief Determine which kind of bridge is being performed via this cast.
1599 ObjCBridgeCastKind getBridgeKind() const {
1600 return static_cast<ObjCBridgeCastKind>(Kind);
1603 /// \brief Retrieve the kind of bridge being performed as a string.
1604 StringRef getBridgeKindName() const;
1606 /// \brief The location of the bridge keyword.
1607 SourceLocation getBridgeKeywordLoc() const { return BridgeKeywordLoc; }
1609 SourceLocation getLocStart() const LLVM_READONLY { return LParenLoc; }
1611 SourceLocation getLocEnd() const LLVM_READONLY {
1612 return getSubExpr()->getLocEnd();
1615 static bool classof(const Stmt *T) {
1616 return T->getStmtClass() == ObjCBridgedCastExprClass;
1620 /// \brief A runtime availability query.
1622 /// There are 2 ways to spell this node:
1624 /// @available(macos 10.10, ios 8, *); // Objective-C
1625 /// __builtin_available(macos 10.10, ios 8, *); // C, C++, and Objective-C
1628 /// Note that we only need to keep track of one \c VersionTuple here, which is
1629 /// the one that corresponds to the current deployment target. This is meant to
1630 /// be used in the condition of an \c if, but it is also usable as top level
1633 class ObjCAvailabilityCheckExpr : public Expr {
1634 friend class ASTStmtReader;
1636 VersionTuple VersionToCheck;
1637 SourceLocation AtLoc, RParen;
1640 ObjCAvailabilityCheckExpr(VersionTuple VersionToCheck, SourceLocation AtLoc,
1641 SourceLocation RParen, QualType Ty)
1642 : Expr(ObjCAvailabilityCheckExprClass, Ty, VK_RValue, OK_Ordinary, false,
1643 false, false, false),
1644 VersionToCheck(VersionToCheck), AtLoc(AtLoc), RParen(RParen) {}
1646 explicit ObjCAvailabilityCheckExpr(EmptyShell Shell)
1647 : Expr(ObjCAvailabilityCheckExprClass, Shell) {}
1649 SourceLocation getLocStart() const { return AtLoc; }
1650 SourceLocation getLocEnd() const { return RParen; }
1651 SourceRange getSourceRange() const { return {AtLoc, RParen}; }
1653 /// \brief This may be '*', in which case this should fold to true.
1654 bool hasVersion() const { return !VersionToCheck.empty(); }
1655 VersionTuple getVersion() { return VersionToCheck; }
1657 child_range children() {
1658 return child_range(child_iterator(), child_iterator());
1661 static bool classof(const Stmt *T) {
1662 return T->getStmtClass() == ObjCAvailabilityCheckExprClass;
1666 } // namespace clang
1668 #endif // LLVM_CLANG_AST_EXPROBJC_H