1//===- ExprObjC.h - Classes for representing ObjC expressions ---*- C++ -*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This file defines the ExprObjC interface and subclasses.
10//
11//===----------------------------------------------------------------------===//
12
13#ifndef LLVM_CLANG_AST_EXPROBJC_H
14#define LLVM_CLANG_AST_EXPROBJC_H
15
16#include "clang/AST/Decl.h"
17#include "clang/AST/DeclObjC.h"
18#include "clang/AST/Expr.h"
19#include "clang/AST/OperationKinds.h"
20#include "clang/AST/SelectorLocationsKind.h"
21#include "clang/AST/Stmt.h"
22#include "clang/AST/Type.h"
23#include "clang/Basic/IdentifierTable.h"
24#include "clang/Basic/LLVM.h"
25#include "clang/Basic/SourceLocation.h"
26#include "clang/Basic/Specifiers.h"
27#include "llvm/ADT/ArrayRef.h"
28#include "llvm/ADT/None.h"
29#include "llvm/ADT/Optional.h"
30#include "llvm/ADT/PointerIntPair.h"
31#include "llvm/ADT/PointerUnion.h"
32#include "llvm/ADT/StringRef.h"
33#include "llvm/ADT/iterator_range.h"
34#include "llvm/Support/Casting.h"
35#include "llvm/Support/Compiler.h"
36#include "llvm/Support/TrailingObjects.h"
37#include "llvm/Support/VersionTuple.h"
38#include "llvm/Support/type_traits.h"
39#include <cassert>
40#include <cstddef>
41#include <cstdint>
42
43namespace clang {
44
45class ASTContext;
46class CXXBaseSpecifier;
47
48/// ObjCStringLiteral, used for Objective-C string literals
49/// i.e. @"foo".
50class ObjCStringLiteral : public Expr {
51 Stmt *String;
52 SourceLocation AtLoc;
53
54public:
55 ObjCStringLiteral(StringLiteral *SL, QualType T, SourceLocation L)
56 : Expr(ObjCStringLiteralClass, T, VK_RValue, OK_Ordinary, false, false,
57 false, false),
58 String(SL), AtLoc(L) {}
59 explicit ObjCStringLiteral(EmptyShell Empty)
60 : Expr(ObjCStringLiteralClass, Empty) {}
61
62 StringLiteral *getString() { return cast<StringLiteral>(String); }
63 const StringLiteral *getString() const { return cast<StringLiteral>(String); }
64 void setString(StringLiteral *S) { String = S; }
65
66 SourceLocation getAtLoc() const { return AtLoc; }
67 void setAtLoc(SourceLocation L) { AtLoc = L; }
68
69 SourceLocation getBeginLoc() const LLVM_READONLY { return AtLoc; }
70 SourceLocation getEndLoc() const LLVM_READONLY { return String->getEndLoc(); }
71
72 // Iterators
73 child_range children() { return child_range(&String, &String+1); }
74
75 static bool classof(const Stmt *T) {
76 return T->getStmtClass() == ObjCStringLiteralClass;
77 }
78};
79
80/// ObjCBoolLiteralExpr - Objective-C Boolean Literal.
81class ObjCBoolLiteralExpr : public Expr {
82 bool Value;
83 SourceLocation Loc;
84
85public:
86 ObjCBoolLiteralExpr(bool val, QualType Ty, SourceLocation l)
87 : Expr(ObjCBoolLiteralExprClass, Ty, VK_RValue, OK_Ordinary, false, false,
88 false, false),
89 Value(val), Loc(l) {}
90 explicit ObjCBoolLiteralExpr(EmptyShell Empty)
91 : Expr(ObjCBoolLiteralExprClass, Empty) {}
92
93 bool getValue() const { return Value; }
94 void setValue(bool V) { Value = V; }
95
96 SourceLocation getBeginLoc() const LLVM_READONLY { return Loc; }
97 SourceLocation getEndLoc() const LLVM_READONLY { return Loc; }
98
99 SourceLocation getLocation() const { return Loc; }
100 void setLocation(SourceLocation L) { Loc = L; }
101
102 // Iterators
103 child_range children() {
104 return child_range(child_iterator(), child_iterator());
105 }
106
107 static bool classof(const Stmt *T) {
108 return T->getStmtClass() == ObjCBoolLiteralExprClass;
109 }
110};
111
112/// ObjCBoxedExpr - used for generalized expression boxing.
113/// as in: @(strdup("hello world")), @(random()) or @(view.frame)
114/// Also used for boxing non-parenthesized numeric literals;
115/// as in: @42 or \@true (c++/objc++) or \@__objc_yes (c/objc).
116class ObjCBoxedExpr : public Expr {
117 Stmt *SubExpr;
118 ObjCMethodDecl *BoxingMethod;
119 SourceRange Range;
120
121public:
122 friend class ASTStmtReader;
123
124 ObjCBoxedExpr(Expr *E, QualType T, ObjCMethodDecl *method,
125 SourceRange R)
126 : Expr(ObjCBoxedExprClass, T, VK_RValue, OK_Ordinary,
127 E->isTypeDependent(), E->isValueDependent(),
128 E->isInstantiationDependent(),
129 E->containsUnexpandedParameterPack()),
130 SubExpr(E), BoxingMethod(method), Range(R) {}
131 explicit ObjCBoxedExpr(EmptyShell Empty)
132 : Expr(ObjCBoxedExprClass, Empty) {}
133
134 Expr *getSubExpr() { return cast<Expr>(SubExpr); }
135 const Expr *getSubExpr() const { return cast<Expr>(SubExpr); }
136
137 ObjCMethodDecl *getBoxingMethod() const {
138 return BoxingMethod;
139 }
140
141 SourceLocation getAtLoc() const { return Range.getBegin(); }
142
143 SourceLocation getBeginLoc() const LLVM_READONLY { return Range.getBegin(); }
144 SourceLocation getEndLoc() const LLVM_READONLY { return Range.getEnd(); }
145
146 SourceRange getSourceRange() const LLVM_READONLY {
147 return Range;
148 }
149
150 // Iterators
151 child_range children() { return child_range(&SubExpr, &SubExpr+1); }
152
153 using const_arg_iterator = ConstExprIterator;
154
155 const_arg_iterator arg_begin() const {
156 return reinterpret_cast<Stmt const * const*>(&SubExpr);
157 }
158
159 const_arg_iterator arg_end() const {
160 return reinterpret_cast<Stmt const * const*>(&SubExpr + 1);
161 }
162
163 static bool classof(const Stmt *T) {
164 return T->getStmtClass() == ObjCBoxedExprClass;
165 }
166};
167
168/// ObjCArrayLiteral - used for objective-c array containers; as in:
169/// @[@"Hello", NSApp, [NSNumber numberWithInt:42]];
170class ObjCArrayLiteral final
171 : public Expr,
172 private llvm::TrailingObjects<ObjCArrayLiteral, Expr *> {
173 unsigned NumElements;
174 SourceRange Range;
175 ObjCMethodDecl *ArrayWithObjectsMethod;
176
177 ObjCArrayLiteral(ArrayRef<Expr *> Elements,
178 QualType T, ObjCMethodDecl * Method,
179 SourceRange SR);
180
181 explicit ObjCArrayLiteral(EmptyShell Empty, unsigned NumElements)
182 : Expr(ObjCArrayLiteralClass, Empty), NumElements(NumElements) {}
183
184public:
185 friend class ASTStmtReader;
186 friend TrailingObjects;
187
188 static ObjCArrayLiteral *Create(const ASTContext &C,
189 ArrayRef<Expr *> Elements,
190 QualType T, ObjCMethodDecl * Method,
191 SourceRange SR);
192
193 static ObjCArrayLiteral *CreateEmpty(const ASTContext &C,
194 unsigned NumElements);
195
196 SourceLocation getBeginLoc() const LLVM_READONLY { return Range.getBegin(); }
197 SourceLocation getEndLoc() const LLVM_READONLY { return Range.getEnd(); }
198 SourceRange getSourceRange() const LLVM_READONLY { return Range; }
199
200 /// Retrieve elements of array of literals.
201 Expr **getElements() { return getTrailingObjects<Expr *>(); }
202
203 /// Retrieve elements of array of literals.
204 const Expr * const *getElements() const {
205 return getTrailingObjects<Expr *>();
206 }
207
208 /// getNumElements - Return number of elements of objective-c array literal.
209 unsigned getNumElements() const { return NumElements; }
210
211 /// getElement - Return the Element at the specified index.
212 Expr *getElement(unsigned Index) {
213 assert((Index < NumElements) && "Arg access out of range!");
214 return getElements()[Index];
215 }
216 const Expr *getElement(unsigned Index) const {
217 assert((Index < NumElements) && "Arg access out of range!");
218 return getElements()[Index];
219 }
220
221 ObjCMethodDecl *getArrayWithObjectsMethod() const {
222 return ArrayWithObjectsMethod;
223 }
224
225 // Iterators
226 child_range children() {
227 return child_range(reinterpret_cast<Stmt **>(getElements()),
228 reinterpret_cast<Stmt **>(getElements()) + NumElements);
229 }
230
231 static bool classof(const Stmt *T) {
232 return T->getStmtClass() == ObjCArrayLiteralClass;
233 }
234};
235
236/// An element in an Objective-C dictionary literal.
237///
238struct ObjCDictionaryElement {
239 /// The key for the dictionary element.
240 Expr *Key;
241
242 /// The value of the dictionary element.
243 Expr *Value;
244
245 /// The location of the ellipsis, if this is a pack expansion.
246 SourceLocation EllipsisLoc;
247
248 /// The number of elements this pack expansion will expand to, if
249 /// this is a pack expansion and is known.
250 Optional<unsigned> NumExpansions;
251
252 /// Determines whether this dictionary element is a pack expansion.
253 bool isPackExpansion() const { return EllipsisLoc.isValid(); }
254};
255
256} // namespace clang
257
258namespace clang {
259
260/// Internal struct for storing Key/value pair.
261struct ObjCDictionaryLiteral_KeyValuePair {
262 Expr *Key;
263 Expr *Value;
264};
265
266/// Internal struct to describes an element that is a pack
267/// expansion, used if any of the elements in the dictionary literal
268/// are pack expansions.
269struct ObjCDictionaryLiteral_ExpansionData {
270 /// The location of the ellipsis, if this element is a pack
271 /// expansion.
272 SourceLocation EllipsisLoc;
273
274 /// If non-zero, the number of elements that this pack
275 /// expansion will expand to (+1).
276 unsigned NumExpansionsPlusOne;
277};
278
279/// ObjCDictionaryLiteral - AST node to represent objective-c dictionary
280/// literals; as in: @{@"name" : NSUserName(), @"date" : [NSDate date] };
281class ObjCDictionaryLiteral final
282 : public Expr,
283 private llvm::TrailingObjects<ObjCDictionaryLiteral,
284 ObjCDictionaryLiteral_KeyValuePair,
285 ObjCDictionaryLiteral_ExpansionData> {
286 /// The number of elements in this dictionary literal.
287 unsigned NumElements : 31;
288
289 /// Determine whether this dictionary literal has any pack expansions.
290 ///
291 /// If the dictionary literal has pack expansions, then there will
292 /// be an array of pack expansion data following the array of
293 /// key/value pairs, which provide the locations of the ellipses (if
294 /// any) and number of elements in the expansion (if known). If
295 /// there are no pack expansions, we optimize away this storage.
296 unsigned HasPackExpansions : 1;
297
298 SourceRange Range;
299 ObjCMethodDecl *DictWithObjectsMethod;
300
301 using KeyValuePair = ObjCDictionaryLiteral_KeyValuePair;
302 using ExpansionData = ObjCDictionaryLiteral_ExpansionData;
303
304 ObjCDictionaryLiteral(ArrayRef<ObjCDictionaryElement> VK,
305 bool HasPackExpansions,
306 QualType T, ObjCMethodDecl *method,
307 SourceRange SR);
308
309 explicit ObjCDictionaryLiteral(EmptyShell Empty, unsigned NumElements,
310 bool HasPackExpansions)
311 : Expr(ObjCDictionaryLiteralClass, Empty), NumElements(NumElements),
312 HasPackExpansions(HasPackExpansions) {}
313
314 size_t numTrailingObjects(OverloadToken<KeyValuePair>) const {
315 return NumElements;
316 }
317
318public:
319 friend class ASTStmtReader;
320 friend class ASTStmtWriter;
321 friend TrailingObjects;
322
323 static ObjCDictionaryLiteral *Create(const ASTContext &C,
324 ArrayRef<ObjCDictionaryElement> VK,
325 bool HasPackExpansions,
326 QualType T, ObjCMethodDecl *method,
327 SourceRange SR);
328
329 static ObjCDictionaryLiteral *CreateEmpty(const ASTContext &C,
330 unsigned NumElements,
331 bool HasPackExpansions);
332
333 /// getNumElements - Return number of elements of objective-c dictionary
334 /// literal.
335 unsigned getNumElements() const { return NumElements; }
336
337 ObjCDictionaryElement getKeyValueElement(unsigned Index) const {
338 assert((Index < NumElements) && "Arg access out of range!");
339 const KeyValuePair &KV = getTrailingObjects<KeyValuePair>()[Index];
340 ObjCDictionaryElement Result = { KV.Key, KV.Value, SourceLocation(), None };
341 if (HasPackExpansions) {
342 const ExpansionData &Expansion =
343 getTrailingObjects<ExpansionData>()[Index];
344 Result.EllipsisLoc = Expansion.EllipsisLoc;
345 if (Expansion.NumExpansionsPlusOne > 0)
346 Result.NumExpansions = Expansion.NumExpansionsPlusOne - 1;
347 }
348 return Result;
349 }
350
351 ObjCMethodDecl *getDictWithObjectsMethod() const {
352 return DictWithObjectsMethod;
353 }
354
355 SourceLocation getBeginLoc() const LLVM_READONLY { return Range.getBegin(); }
356 SourceLocation getEndLoc() const LLVM_READONLY { return Range.getEnd(); }
357 SourceRange getSourceRange() const LLVM_READONLY { return Range; }
358
359 // Iterators
360 child_range children() {
361 // Note: we're taking advantage of the layout of the KeyValuePair struct
362 // here. If that struct changes, this code will need to change as well.
363 static_assert(sizeof(KeyValuePair) == sizeof(Stmt *) * 2,
364 "KeyValuePair is expected size");
365 return child_range(
366 reinterpret_cast<Stmt **>(getTrailingObjects<KeyValuePair>()),
367 reinterpret_cast<Stmt **>(getTrailingObjects<KeyValuePair>()) +
368 NumElements * 2);
369 }
370
371 static bool classof(const Stmt *T) {
372 return T->getStmtClass() == ObjCDictionaryLiteralClass;
373 }
374};
375
376/// ObjCEncodeExpr, used for \@encode in Objective-C. \@encode has the same
377/// type and behavior as StringLiteral except that the string initializer is
378/// obtained from ASTContext with the encoding type as an argument.
379class ObjCEncodeExpr : public Expr {
380 TypeSourceInfo *EncodedType;
381 SourceLocation AtLoc, RParenLoc;
382
383public:
384 ObjCEncodeExpr(QualType T, TypeSourceInfo *EncodedType,
385 SourceLocation at, SourceLocation rp)
386 : Expr(ObjCEncodeExprClass, T, VK_LValue, OK_Ordinary,
387 EncodedType->getType()->isDependentType(),
388 EncodedType->getType()->isDependentType(),
389 EncodedType->getType()->isInstantiationDependentType(),
390 EncodedType->getType()->containsUnexpandedParameterPack()),
391 EncodedType(EncodedType), AtLoc(at), RParenLoc(rp) {}
392
393 explicit ObjCEncodeExpr(EmptyShell Empty) : Expr(ObjCEncodeExprClass, Empty){}
394
395 SourceLocation getAtLoc() const { return AtLoc; }
396 void setAtLoc(SourceLocation L) { AtLoc = L; }
397 SourceLocation getRParenLoc() const { return RParenLoc; }
398 void setRParenLoc(SourceLocation L) { RParenLoc = L; }
399
400 QualType getEncodedType() const { return EncodedType->getType(); }
401
402 TypeSourceInfo *getEncodedTypeSourceInfo() const { return EncodedType; }
403
404 void setEncodedTypeSourceInfo(TypeSourceInfo *EncType) {
405 EncodedType = EncType;
406 }
407
408 SourceLocation getBeginLoc() const LLVM_READONLY { return AtLoc; }
409 SourceLocation getEndLoc() const LLVM_READONLY { return RParenLoc; }
410
411 // Iterators
412 child_range children() {
413 return child_range(child_iterator(), child_iterator());
414 }
415
416 static bool classof(const Stmt *T) {
417 return T->getStmtClass() == ObjCEncodeExprClass;
418 }
419};
420
421/// ObjCSelectorExpr used for \@selector in Objective-C.
422class ObjCSelectorExpr : public Expr {
423 Selector SelName;
424 SourceLocation AtLoc, RParenLoc;
425
426public:
427 ObjCSelectorExpr(QualType T, Selector selInfo,
428 SourceLocation at, SourceLocation rp)
429 : Expr(ObjCSelectorExprClass, T, VK_RValue, OK_Ordinary, false, false,
430 false, false),
431 SelName(selInfo), AtLoc(at), RParenLoc(rp) {}
432 explicit ObjCSelectorExpr(EmptyShell Empty)
433 : Expr(ObjCSelectorExprClass, Empty) {}
434
435 Selector getSelector() const { return SelName; }
436 void setSelector(Selector S) { SelName = S; }
437
438 SourceLocation getAtLoc() const { return AtLoc; }
439 SourceLocation getRParenLoc() const { return RParenLoc; }
440 void setAtLoc(SourceLocation L) { AtLoc = L; }
441 void setRParenLoc(SourceLocation L) { RParenLoc = L; }
442
443 SourceLocation getBeginLoc() const LLVM_READONLY { return AtLoc; }
444 SourceLocation getEndLoc() const LLVM_READONLY { return RParenLoc; }
445
446 /// getNumArgs - Return the number of actual arguments to this call.
447 unsigned getNumArgs() const { return SelName.getNumArgs(); }
448
449 // Iterators
450 child_range children() {
451 return child_range(child_iterator(), child_iterator());
452 }
453
454 static bool classof(const Stmt *T) {
455 return T->getStmtClass() == ObjCSelectorExprClass;
456 }
457};
458
459/// ObjCProtocolExpr used for protocol expression in Objective-C.
460///
461/// This is used as: \@protocol(foo), as in:
462/// \code
463/// [obj conformsToProtocol:@protocol(foo)]
464/// \endcode
465///
466/// The return type is "Protocol*".
467class ObjCProtocolExpr : public Expr {
468 ObjCProtocolDecl *TheProtocol;
469 SourceLocation AtLoc, ProtoLoc, RParenLoc;
470
471public:
472 friend class ASTStmtReader;
473 friend class ASTStmtWriter;
474
475 ObjCProtocolExpr(QualType T, ObjCProtocolDecl *protocol,
476 SourceLocation at, SourceLocation protoLoc, SourceLocation rp)
477 : Expr(ObjCProtocolExprClass, T, VK_RValue, OK_Ordinary, false, false,
478 false, false),
479 TheProtocol(protocol), AtLoc(at), ProtoLoc(protoLoc), RParenLoc(rp) {}
480 explicit ObjCProtocolExpr(EmptyShell Empty)
481 : Expr(ObjCProtocolExprClass, Empty) {}
482
483 ObjCProtocolDecl *getProtocol() const { return TheProtocol; }
484 void setProtocol(ObjCProtocolDecl *P) { TheProtocol = P; }
485
486 SourceLocation getProtocolIdLoc() const { return ProtoLoc; }
487 SourceLocation getAtLoc() const { return AtLoc; }
488 SourceLocation getRParenLoc() const { return RParenLoc; }
489 void setAtLoc(SourceLocation L) { AtLoc = L; }
490 void setRParenLoc(SourceLocation L) { RParenLoc = L; }
491
492 SourceLocation getBeginLoc() const LLVM_READONLY { return AtLoc; }
493 SourceLocation getEndLoc() const LLVM_READONLY { return RParenLoc; }
494
495 // Iterators
496 child_range children() {
497 return child_range(child_iterator(), child_iterator());
498 }
499
500 static bool classof(const Stmt *T) {
501 return T->getStmtClass() == ObjCProtocolExprClass;
502 }
503};
504
505/// ObjCIvarRefExpr - A reference to an ObjC instance variable.
506class ObjCIvarRefExpr : public Expr {
507 ObjCIvarDecl *D;
508 Stmt *Base;
509 SourceLocation Loc;
510
511 /// OpLoc - This is the location of '.' or '->'
512 SourceLocation OpLoc;
513
514 // True if this is "X->F", false if this is "X.F".
515 bool IsArrow : 1;
516
517 // True if ivar reference has no base (self assumed).
518 bool IsFreeIvar : 1;
519
520public:
521 ObjCIvarRefExpr(ObjCIvarDecl *d, QualType t,
522 SourceLocation l, SourceLocation oploc,
523 Expr *base,
524 bool arrow = false, bool freeIvar = false)
525 : Expr(ObjCIvarRefExprClass, t, VK_LValue,
526 d->isBitField() ? OK_BitField : OK_Ordinary,
527 /*TypeDependent=*/false, base->isValueDependent(),
528 base->isInstantiationDependent(),
529 base->containsUnexpandedParameterPack()),
530 D(d), Base(base), Loc(l), OpLoc(oploc), IsArrow(arrow),
531 IsFreeIvar(freeIvar) {}
532
533 explicit ObjCIvarRefExpr(EmptyShell Empty)
534 : Expr(ObjCIvarRefExprClass, Empty) {}
535
536 ObjCIvarDecl *getDecl() { return D; }
537 const ObjCIvarDecl *getDecl() const { return D; }
538 void setDecl(ObjCIvarDecl *d) { D = d; }
539
540 const Expr *getBase() const { return cast<Expr>(Base); }
541 Expr *getBase() { return cast<Expr>(Base); }
542 void setBase(Expr * base) { Base = base; }
543
544 bool isArrow() const { return IsArrow; }
545 bool isFreeIvar() const { return IsFreeIvar; }
546 void setIsArrow(bool A) { IsArrow = A; }
547 void setIsFreeIvar(bool A) { IsFreeIvar = A; }
548
549 SourceLocation getLocation() const { return Loc; }
550 void setLocation(SourceLocation L) { Loc = L; }
551
552 SourceLocation getBeginLoc() const LLVM_READONLY {
553 return isFreeIvar() ? Loc : getBase()->getBeginLoc();
554 }
555 SourceLocation getEndLoc() const LLVM_READONLY { return Loc; }
556
557 SourceLocation getOpLoc() const { return OpLoc; }
558 void setOpLoc(SourceLocation L) { OpLoc = L; }
559
560 // Iterators
561 child_range children() { return child_range(&Base, &Base+1); }
562
563 static bool classof(const Stmt *T) {
564 return T->getStmtClass() == ObjCIvarRefExprClass;
565 }
566};
567
568/// ObjCPropertyRefExpr - A dot-syntax expression to access an ObjC
569/// property.
570class ObjCPropertyRefExpr : public Expr {
571private:
572 /// If the bool is true, this is an implicit property reference; the
573 /// pointer is an (optional) ObjCMethodDecl and Setter may be set.
574 /// if the bool is false, this is an explicit property reference;
575 /// the pointer is an ObjCPropertyDecl and Setter is always null.
576 llvm::PointerIntPair<NamedDecl *, 1, bool> PropertyOrGetter;
577
578 /// Indicates whether the property reference will result in a message
579 /// to the getter, the setter, or both.
580 /// This applies to both implicit and explicit property references.
581 enum MethodRefFlags {
582 MethodRef_None = 0,
583 MethodRef_Getter = 0x1,
584 MethodRef_Setter = 0x2
585 };
586
587 /// Contains the Setter method pointer and MethodRefFlags bit flags.
588 llvm::PointerIntPair<ObjCMethodDecl *, 2, unsigned> SetterAndMethodRefFlags;
589
590 // FIXME: Maybe we should store the property identifier here,
591 // because it's not rederivable from the other data when there's an
592 // implicit property with no getter (because the 'foo' -> 'setFoo:'
593 // transformation is lossy on the first character).
594
595 SourceLocation IdLoc;
596
597 /// When the receiver in property access is 'super', this is
598 /// the location of the 'super' keyword. When it's an interface,
599 /// this is that interface.
600 SourceLocation ReceiverLoc;
601 llvm::PointerUnion3<Stmt *, const Type *, ObjCInterfaceDecl *> Receiver;
602
603public:
604 ObjCPropertyRefExpr(ObjCPropertyDecl *PD, QualType t,
605 ExprValueKind VK, ExprObjectKind OK,
606 SourceLocation l, Expr *base)
607 : Expr(ObjCPropertyRefExprClass, t, VK, OK,
608 /*TypeDependent=*/false, base->isValueDependent(),
609 base->isInstantiationDependent(),
610 base->containsUnexpandedParameterPack()),
611 PropertyOrGetter(PD, false), IdLoc(l), Receiver(base) {
612 assert(t->isSpecificPlaceholderType(BuiltinType::PseudoObject));
613 }
614
615 ObjCPropertyRefExpr(ObjCPropertyDecl *PD, QualType t,
616 ExprValueKind VK, ExprObjectKind OK,
617 SourceLocation l, SourceLocation sl, QualType st)
618 : Expr(ObjCPropertyRefExprClass, t, VK, OK,
619 /*TypeDependent=*/false, false, st->isInstantiationDependentType(),
620 st->containsUnexpandedParameterPack()),
621 PropertyOrGetter(PD, false), IdLoc(l), ReceiverLoc(sl),
622 Receiver(st.getTypePtr()) {
623 assert(t->isSpecificPlaceholderType(BuiltinType::PseudoObject));
624 }
625
626 ObjCPropertyRefExpr(ObjCMethodDecl *Getter, ObjCMethodDecl *Setter,
627 QualType T, ExprValueKind VK, ExprObjectKind OK,
628 SourceLocation IdLoc, Expr *Base)
629 : Expr(ObjCPropertyRefExprClass, T, VK, OK, false,
630 Base->isValueDependent(), Base->isInstantiationDependent(),
631 Base->containsUnexpandedParameterPack()),
632 PropertyOrGetter(Getter, true), SetterAndMethodRefFlags(Setter, 0),
633 IdLoc(IdLoc), Receiver(Base) {
634 assert(T->isSpecificPlaceholderType(BuiltinType::PseudoObject));
635 }
636
637 ObjCPropertyRefExpr(ObjCMethodDecl *Getter, ObjCMethodDecl *Setter,
638 QualType T, ExprValueKind VK, ExprObjectKind OK,
639 SourceLocation IdLoc,
640 SourceLocation SuperLoc, QualType SuperTy)
641 : Expr(ObjCPropertyRefExprClass, T, VK, OK, false, false, false, false),
642 PropertyOrGetter(Getter, true), SetterAndMethodRefFlags(Setter, 0),
643 IdLoc(IdLoc), ReceiverLoc(SuperLoc), Receiver(SuperTy.getTypePtr()) {
644 assert(T->isSpecificPlaceholderType(BuiltinType::PseudoObject));
645 }
646
647 ObjCPropertyRefExpr(ObjCMethodDecl *Getter, ObjCMethodDecl *Setter,
648 QualType T, ExprValueKind VK, ExprObjectKind OK,
649 SourceLocation IdLoc,
650 SourceLocation ReceiverLoc, ObjCInterfaceDecl *Receiver)
651 : Expr(ObjCPropertyRefExprClass, T, VK, OK, false, false, false, false),
652 PropertyOrGetter(Getter, true), SetterAndMethodRefFlags(Setter, 0),
653 IdLoc(IdLoc), ReceiverLoc(ReceiverLoc), Receiver(Receiver) {
654 assert(T->isSpecificPlaceholderType(BuiltinType::PseudoObject));
655 }
656
657 explicit ObjCPropertyRefExpr(EmptyShell Empty)
658 : Expr(ObjCPropertyRefExprClass, Empty) {}
659
660 bool isImplicitProperty() const { return PropertyOrGetter.getInt(); }
661 bool isExplicitProperty() const { return !PropertyOrGetter.getInt(); }
662
663 ObjCPropertyDecl *getExplicitProperty() const {
664 assert(!isImplicitProperty());
665 return cast<ObjCPropertyDecl>(PropertyOrGetter.getPointer());
666 }
667
668 ObjCMethodDecl *getImplicitPropertyGetter() const {
669 assert(isImplicitProperty());
670 return cast_or_null<ObjCMethodDecl>(PropertyOrGetter.getPointer());
671 }
672
673 ObjCMethodDecl *getImplicitPropertySetter() const {
674 assert(isImplicitProperty());
675 return SetterAndMethodRefFlags.getPointer();
676 }
677
678 Selector getGetterSelector() const {
679 if (isImplicitProperty())
680 return getImplicitPropertyGetter()->getSelector();
681 return getExplicitProperty()->getGetterName();
682 }
683
684 Selector getSetterSelector() const {
685 if (isImplicitProperty())
686 return getImplicitPropertySetter()->getSelector();
687 return getExplicitProperty()->getSetterName();
688 }
689
690 /// True if the property reference will result in a message to the
691 /// getter.
692 /// This applies to both implicit and explicit property references.
693 bool isMessagingGetter() const {
694 return SetterAndMethodRefFlags.getInt() & MethodRef_Getter;
695 }
696
697 /// True if the property reference will result in a message to the
698 /// setter.
699 /// This applies to both implicit and explicit property references.
700 bool isMessagingSetter() const {
701 return SetterAndMethodRefFlags.getInt() & MethodRef_Setter;
702 }
703
704 void setIsMessagingGetter(bool val = true) {
705 setMethodRefFlag(MethodRef_Getter, val);
706 }
707
708 void setIsMessagingSetter(bool val = true) {
709 setMethodRefFlag(MethodRef_Setter, val);
710 }
711
712 const Expr *getBase() const {
713 return cast<Expr>(Receiver.get<Stmt*>());
714 }
715 Expr *getBase() {
716 return cast<Expr>(Receiver.get<Stmt*>());
717 }
718
719 SourceLocation getLocation() const { return IdLoc; }
720
721 SourceLocation getReceiverLocation() const { return ReceiverLoc; }
722
723 QualType getSuperReceiverType() const {
724 return QualType(Receiver.get<const Type*>(), 0);
725 }
726
727 ObjCInterfaceDecl *getClassReceiver() const {
728 return Receiver.get<ObjCInterfaceDecl*>();
729 }
730
731 bool isObjectReceiver() const { return Receiver.is<Stmt*>(); }
732 bool isSuperReceiver() const { return Receiver.is<const Type*>(); }
733 bool isClassReceiver() const { return Receiver.is<ObjCInterfaceDecl*>(); }
734
735 /// Determine the type of the base, regardless of the kind of receiver.
736 QualType getReceiverType(const ASTContext &ctx) const;
737
738 SourceLocation getBeginLoc() const LLVM_READONLY {
739 return isObjectReceiver() ? getBase()->getBeginLoc()
740 : getReceiverLocation();
741 }
742
743 SourceLocation getEndLoc() const LLVM_READONLY { return IdLoc; }
744
745 // Iterators
746 child_range children() {
747 if (Receiver.is<Stmt*>()) {
748 Stmt **begin = reinterpret_cast<Stmt**>(&Receiver); // hack!
749 return child_range(begin, begin+1);
750 }
751 return child_range(child_iterator(), child_iterator());
752 }
753
754 static bool classof(const Stmt *T) {
755 return T->getStmtClass() == ObjCPropertyRefExprClass;
756 }
757
758private:
759 friend class ASTStmtReader;
760 friend class ASTStmtWriter;
761
762 void setExplicitProperty(ObjCPropertyDecl *D, unsigned methRefFlags) {
763 PropertyOrGetter.setPointer(D);
764 PropertyOrGetter.setInt(false);
765 SetterAndMethodRefFlags.setPointer(nullptr);
766 SetterAndMethodRefFlags.setInt(methRefFlags);
767 }
768
769 void setImplicitProperty(ObjCMethodDecl *Getter, ObjCMethodDecl *Setter,
770 unsigned methRefFlags) {
771 PropertyOrGetter.setPointer(Getter);
772 PropertyOrGetter.setInt(true);
773 SetterAndMethodRefFlags.setPointer(Setter);
774 SetterAndMethodRefFlags.setInt(methRefFlags);
775 }
776
777 void setBase(Expr *Base) { Receiver = Base; }
778 void setSuperReceiver(QualType T) { Receiver = T.getTypePtr(); }
779 void setClassReceiver(ObjCInterfaceDecl *D) { Receiver = D; }
780
781 void setLocation(SourceLocation L) { IdLoc = L; }
782 void setReceiverLocation(SourceLocation Loc) { ReceiverLoc = Loc; }
783
784 void setMethodRefFlag(MethodRefFlags flag, bool val) {
785 unsigned f = SetterAndMethodRefFlags.getInt();
786 if (val)
787 f |= flag;
788 else
789 f &= ~flag;
790 SetterAndMethodRefFlags.setInt(f);
791 }
792};
793
794/// ObjCSubscriptRefExpr - used for array and dictionary subscripting.
795/// array[4] = array[3]; dictionary[key] = dictionary[alt_key];
796class ObjCSubscriptRefExpr : public Expr {
797 // Location of ']' in an indexing expression.
798 SourceLocation RBracket;
799
800 // array/dictionary base expression.
801 // for arrays, this is a numeric expression. For dictionaries, this is
802 // an objective-c object pointer expression.
803 enum { BASE, KEY, END_EXPR };
804 Stmt* SubExprs[END_EXPR];
805
806 ObjCMethodDecl *GetAtIndexMethodDecl;
807
808 // For immutable objects this is null. When ObjCSubscriptRefExpr is to read
809 // an indexed object this is null too.
810 ObjCMethodDecl *SetAtIndexMethodDecl;
811
812public:
813 ObjCSubscriptRefExpr(Expr *base, Expr *key, QualType T,
814 ExprValueKind VK, ExprObjectKind OK,
815 ObjCMethodDecl *getMethod,
816 ObjCMethodDecl *setMethod, SourceLocation RB)
817 : Expr(ObjCSubscriptRefExprClass, T, VK, OK,
818 base->isTypeDependent() || key->isTypeDependent(),
819 base->isValueDependent() || key->isValueDependent(),
820 (base->isInstantiationDependent() ||
821 key->isInstantiationDependent()),
822 (base->containsUnexpandedParameterPack() ||
823 key->containsUnexpandedParameterPack())),
824 RBracket(RB), GetAtIndexMethodDecl(getMethod),
825 SetAtIndexMethodDecl(setMethod) {
826 SubExprs[BASE] = base; SubExprs[KEY] = key;
827 }
828
829 explicit ObjCSubscriptRefExpr(EmptyShell Empty)
830 : Expr(ObjCSubscriptRefExprClass, Empty) {}
831
832 SourceLocation getRBracket() const { return RBracket; }
833 void setRBracket(SourceLocation RB) { RBracket = RB; }
834
835 SourceLocation getBeginLoc() const LLVM_READONLY {
836 return SubExprs[BASE]->getBeginLoc();
837 }
838
839 SourceLocation getEndLoc() const LLVM_READONLY { return RBracket; }
840
841 Expr *getBaseExpr() const { return cast<Expr>(SubExprs[BASE]); }
842 void setBaseExpr(Stmt *S) { SubExprs[BASE] = S; }
843
844 Expr *getKeyExpr() const { return cast<Expr>(SubExprs[KEY]); }
845 void setKeyExpr(Stmt *S) { SubExprs[KEY] = S; }
846
847 ObjCMethodDecl *getAtIndexMethodDecl() const {
848 return GetAtIndexMethodDecl;
849 }
850
851 ObjCMethodDecl *setAtIndexMethodDecl() const {
852 return SetAtIndexMethodDecl;
853 }
854
855 bool isArraySubscriptRefExpr() const {
856 return getKeyExpr()->getType()->isIntegralOrEnumerationType();
857 }
858
859 child_range children() {
860 return child_range(SubExprs, SubExprs+END_EXPR);
861 }
862
863 static bool classof(const Stmt *T) {
864 return T->getStmtClass() == ObjCSubscriptRefExprClass;
865 }
866
867private:
868 friend class ASTStmtReader;
869};
870
871/// An expression that sends a message to the given Objective-C
872/// object or class.
873///
874/// The following contains two message send expressions:
875///
876/// \code
877/// [[NSString alloc] initWithString:@"Hello"]
878/// \endcode
879///
880/// The innermost message send invokes the "alloc" class method on the
881/// NSString class, while the outermost message send invokes the
882/// "initWithString" instance method on the object returned from
883/// NSString's "alloc". In all, an Objective-C message send can take
884/// on four different (although related) forms:
885///
886/// 1. Send to an object instance.
887/// 2. Send to a class.
888/// 3. Send to the superclass instance of the current class.
889/// 4. Send to the superclass of the current class.
890///
891/// All four kinds of message sends are modeled by the ObjCMessageExpr
892/// class, and can be distinguished via \c getReceiverKind(). Example:
893///
894/// The "void *" trailing objects are actually ONE void * (the
895/// receiver pointer), and NumArgs Expr *. But due to the
896/// implementation of children(), these must be together contiguously.
897class ObjCMessageExpr final
898 : public Expr,
899 private llvm::TrailingObjects<ObjCMessageExpr, void *, SourceLocation> {
900 /// Stores either the selector that this message is sending
901 /// to (when \c HasMethod is zero) or an \c ObjCMethodDecl pointer
902 /// referring to the method that we type-checked against.
903 uintptr_t SelectorOrMethod = 0;
904
905 enum { NumArgsBitWidth = 16 };
906
907 /// The number of arguments in the message send, not
908 /// including the receiver.
909 unsigned NumArgs : NumArgsBitWidth;
910
911 /// The kind of message send this is, which is one of the
912 /// ReceiverKind values.
913 ///
914 /// We pad this out to a byte to avoid excessive masking and shifting.
915 unsigned Kind : 8;
916
917 /// Whether we have an actual method prototype in \c
918 /// SelectorOrMethod.
919 ///
920 /// When non-zero, we have a method declaration; otherwise, we just
921 /// have a selector.
922 unsigned HasMethod : 1;
923
924 /// Whether this message send is a "delegate init call",
925 /// i.e. a call of an init method on self from within an init method.
926 unsigned IsDelegateInitCall : 1;
927
928 /// Whether this message send was implicitly generated by
929 /// the implementation rather than explicitly written by the user.
930 unsigned IsImplicit : 1;
931
932 /// Whether the locations of the selector identifiers are in a
933 /// "standard" position, a enum SelectorLocationsKind.
934 unsigned SelLocsKind : 2;
935
936 /// When the message expression is a send to 'super', this is
937 /// the location of the 'super' keyword.
938 SourceLocation SuperLoc;
939
940 /// The source locations of the open and close square
941 /// brackets ('[' and ']', respectively).
942 SourceLocation LBracLoc, RBracLoc;
943
944 ObjCMessageExpr(EmptyShell Empty, unsigned NumArgs)
945 : Expr(ObjCMessageExprClass, Empty), Kind(0), HasMethod(false),
946 IsDelegateInitCall(false), IsImplicit(false), SelLocsKind(0) {
947 setNumArgs(NumArgs);
948 }
949
950 ObjCMessageExpr(QualType T, ExprValueKind VK,
951 SourceLocation LBracLoc,
952 SourceLocation SuperLoc,
953 bool IsInstanceSuper,
954 QualType SuperType,
955 Selector Sel,
956 ArrayRef<SourceLocation> SelLocs,
957 SelectorLocationsKind SelLocsK,
958 ObjCMethodDecl *Method,
959 ArrayRef<Expr *> Args,
960 SourceLocation RBracLoc,
961 bool isImplicit);
962 ObjCMessageExpr(QualType T, ExprValueKind VK,
963 SourceLocation LBracLoc,
964 TypeSourceInfo *Receiver,
965 Selector Sel,
966 ArrayRef<SourceLocation> SelLocs,
967 SelectorLocationsKind SelLocsK,
968 ObjCMethodDecl *Method,
969 ArrayRef<Expr *> Args,
970 SourceLocation RBracLoc,
971 bool isImplicit);
972 ObjCMessageExpr(QualType T, ExprValueKind VK,
973 SourceLocation LBracLoc,
974 Expr *Receiver,
975 Selector Sel,
976 ArrayRef<SourceLocation> SelLocs,
977 SelectorLocationsKind SelLocsK,
978 ObjCMethodDecl *Method,
979 ArrayRef<Expr *> Args,
980 SourceLocation RBracLoc,
981 bool isImplicit);
982
983 size_t numTrailingObjects(OverloadToken<void *>) const { return NumArgs + 1; }
984
985 void setNumArgs(unsigned Num) {
986 assert((Num >> NumArgsBitWidth) == 0 && "Num of args is out of range!");
987 NumArgs = Num;
988 }
989
990 void initArgsAndSelLocs(ArrayRef<Expr *> Args,
991 ArrayRef<SourceLocation> SelLocs,
992 SelectorLocationsKind SelLocsK);
993
994 /// Retrieve the pointer value of the message receiver.
995 void *getReceiverPointer() const { return *getTrailingObjects<void *>(); }
996
997 /// Set the pointer value of the message receiver.
998 void setReceiverPointer(void *Value) {
999 *getTrailingObjects<void *>() = Value;
1000 }
1001
1002 SelectorLocationsKind getSelLocsKind() const {
1003 return (SelectorLocationsKind)SelLocsKind;
1004 }
1005
1006 bool hasStandardSelLocs() const {
1007 return getSelLocsKind() != SelLoc_NonStandard;
1008 }
1009
1010 /// Get a pointer to the stored selector identifiers locations array.
1011 /// No locations will be stored if HasStandardSelLocs is true.
1012 SourceLocation *getStoredSelLocs() {
1013 return getTrailingObjects<SourceLocation>();
1014 }
1015 const SourceLocation *getStoredSelLocs() const {
1016 return getTrailingObjects<SourceLocation>();
1017 }
1018
1019 /// Get the number of stored selector identifiers locations.
1020 /// No locations will be stored if HasStandardSelLocs is true.
1021 unsigned getNumStoredSelLocs() const {
1022 if (hasStandardSelLocs())
1023 return 0;
1024 return getNumSelectorLocs();
1025 }
1026
1027 static ObjCMessageExpr *alloc(const ASTContext &C,
1028 ArrayRef<Expr *> Args,
1029 SourceLocation RBraceLoc,
1030 ArrayRef<SourceLocation> SelLocs,
1031 Selector Sel,
1032 SelectorLocationsKind &SelLocsK);
1033 static ObjCMessageExpr *alloc(const ASTContext &C,
1034 unsigned NumArgs,
1035 unsigned NumStoredSelLocs);
1036
1037public:
1038 friend class ASTStmtReader;
1039 friend class ASTStmtWriter;
1040 friend TrailingObjects;
1041
1042 /// The kind of receiver this message is sending to.
1043 enum ReceiverKind {
1044 /// The receiver is a class.
1045 Class = 0,
1046
1047 /// The receiver is an object instance.
1048 Instance,
1049
1050 /// The receiver is a superclass.
1051 SuperClass,
1052
1053 /// The receiver is the instance of the superclass object.
1054 SuperInstance
1055 };
1056
1057 /// Create a message send to super.
1058 ///
1059 /// \param Context The ASTContext in which this expression will be created.
1060 ///
1061 /// \param T The result type of this message.
1062 ///
1063 /// \param VK The value kind of this message. A message returning
1064 /// a l-value or r-value reference will be an l-value or x-value,
1065 /// respectively.
1066 ///
1067 /// \param LBracLoc The location of the open square bracket '['.
1068 ///
1069 /// \param SuperLoc The location of the "super" keyword.
1070 ///
1071 /// \param IsInstanceSuper Whether this is an instance "super"
1072 /// message (otherwise, it's a class "super" message).
1073 ///
1074 /// \param Sel The selector used to determine which method gets called.
1075 ///
1076 /// \param Method The Objective-C method against which this message
1077 /// send was type-checked. May be nullptr.
1078 ///
1079 /// \param Args The message send arguments.
1080 ///
1081 /// \param RBracLoc The location of the closing square bracket ']'.
1082 static ObjCMessageExpr *Create(const ASTContext &Context, QualType T,
1083 ExprValueKind VK,
1084 SourceLocation LBracLoc,
1085 SourceLocation SuperLoc,
1086 bool IsInstanceSuper,
1087 QualType SuperType,
1088 Selector Sel,
1089 ArrayRef<SourceLocation> SelLocs,
1090 ObjCMethodDecl *Method,
1091 ArrayRef<Expr *> Args,
1092 SourceLocation RBracLoc,
1093 bool isImplicit);
1094
1095 /// Create a class message send.
1096 ///
1097 /// \param Context The ASTContext in which this expression will be created.
1098 ///
1099 /// \param T The result type of this message.
1100 ///
1101 /// \param VK The value kind of this message. A message returning
1102 /// a l-value or r-value reference will be an l-value or x-value,
1103 /// respectively.
1104 ///
1105 /// \param LBracLoc The location of the open square bracket '['.
1106 ///
1107 /// \param Receiver The type of the receiver, including
1108 /// source-location information.
1109 ///
1110 /// \param Sel The selector used to determine which method gets called.
1111 ///
1112 /// \param Method The Objective-C method against which this message
1113 /// send was type-checked. May be nullptr.
1114 ///
1115 /// \param Args The message send arguments.
1116 ///
1117 /// \param RBracLoc The location of the closing square bracket ']'.
1118 static ObjCMessageExpr *Create(const ASTContext &Context, QualType T,
1119 ExprValueKind VK,
1120 SourceLocation LBracLoc,
1121 TypeSourceInfo *Receiver,
1122 Selector Sel,
1123 ArrayRef<SourceLocation> SelLocs,
1124 ObjCMethodDecl *Method,
1125 ArrayRef<Expr *> Args,
1126 SourceLocation RBracLoc,
1127 bool isImplicit);
1128
1129 /// Create an instance message send.
1130 ///
1131 /// \param Context The ASTContext in which this expression will be created.
1132 ///
1133 /// \param T The result type of this message.
1134 ///
1135 /// \param VK The value kind of this message. A message returning
1136 /// a l-value or r-value reference will be an l-value or x-value,
1137 /// respectively.
1138 ///
1139 /// \param LBracLoc The location of the open square bracket '['.
1140 ///
1141 /// \param Receiver The expression used to produce the object that
1142 /// will receive this message.
1143 ///
1144 /// \param Sel The selector used to determine which method gets called.
1145 ///
1146 /// \param Method The Objective-C method against which this message
1147 /// send was type-checked. May be nullptr.
1148 ///
1149 /// \param Args The message send arguments.
1150 ///
1151 /// \param RBracLoc The location of the closing square bracket ']'.
1152 static ObjCMessageExpr *Create(const ASTContext &Context, QualType T,
1153 ExprValueKind VK,
1154 SourceLocation LBracLoc,
1155 Expr *Receiver,
1156 Selector Sel,
1157 ArrayRef<SourceLocation> SeLocs,
1158 ObjCMethodDecl *Method,
1159 ArrayRef<Expr *> Args,
1160 SourceLocation RBracLoc,
1161 bool isImplicit);
1162
1163 /// Create an empty Objective-C message expression, to be
1164 /// filled in by subsequent calls.
1165 ///
1166 /// \param Context The context in which the message send will be created.
1167 ///
1168 /// \param NumArgs The number of message arguments, not including
1169 /// the receiver.
1170 static ObjCMessageExpr *CreateEmpty(const ASTContext &Context,
1171 unsigned NumArgs,
1172 unsigned NumStoredSelLocs);
1173
1174 /// Indicates whether the message send was implicitly
1175 /// generated by the implementation. If false, it was written explicitly
1176 /// in the source code.
1177 bool isImplicit() const { return IsImplicit; }
1178
1179 /// Determine the kind of receiver that this message is being
1180 /// sent to.
1181 ReceiverKind getReceiverKind() const { return (ReceiverKind)Kind; }
1182
1183 /// \return the return type of the message being sent.
1184 /// This is not always the type of the message expression itself because
1185 /// of references (the expression would not have a reference type).
1186 /// It is also not always the declared return type of the method because
1187 /// of `instancetype` (in that case it's an expression type).
1188 QualType getCallReturnType(ASTContext &Ctx) const;
1189
1190 /// Source range of the receiver.
1191 SourceRange getReceiverRange() const;
1192
1193 /// Determine whether this is an instance message to either a
1194 /// computed object or to super.
1195 bool isInstanceMessage() const {
1196 return getReceiverKind() == Instance || getReceiverKind() == SuperInstance;
1197 }
1198
1199 /// Determine whether this is an class message to either a
1200 /// specified class or to super.
1201 bool isClassMessage() const {
1202 return getReceiverKind() == Class || getReceiverKind() == SuperClass;
1203 }
1204
1205 /// Returns the object expression (receiver) for an instance message,
1206 /// or null for a message that is not an instance message.
1207 Expr *getInstanceReceiver() {
1208 if (getReceiverKind() == Instance)
1209 return static_cast<Expr *>(getReceiverPointer());
1210
1211 return nullptr;
1212 }
1213 const Expr *getInstanceReceiver() const {
1214 return const_cast<ObjCMessageExpr*>(this)->getInstanceReceiver();
1215 }
1216
1217 /// Turn this message send into an instance message that
1218 /// computes the receiver object with the given expression.
1219 void setInstanceReceiver(Expr *rec) {
1220 Kind = Instance;
1221 setReceiverPointer(rec);
1222 }
1223
1224 /// Returns the type of a class message send, or NULL if the
1225 /// message is not a class message.
1226 QualType getClassReceiver() const {
1227 if (TypeSourceInfo *TSInfo = getClassReceiverTypeInfo())
1228 return TSInfo->getType();
1229
1230 return {};
1231 }
1232
1233 /// Returns a type-source information of a class message
1234 /// send, or nullptr if the message is not a class message.
1235 TypeSourceInfo *getClassReceiverTypeInfo() const {
1236 if (getReceiverKind() == Class)
1237 return reinterpret_cast<TypeSourceInfo *>(getReceiverPointer());
1238 return nullptr;
1239 }
1240
1241 void setClassReceiver(TypeSourceInfo *TSInfo) {
1242 Kind = Class;
1243 setReceiverPointer(TSInfo);
1244 }
1245
1246 /// Retrieve the location of the 'super' keyword for a class
1247 /// or instance message to 'super', otherwise an invalid source location.
1248 SourceLocation getSuperLoc() const {
1249 if (getReceiverKind() == SuperInstance || getReceiverKind() == SuperClass)
1250 return SuperLoc;
1251
1252 return SourceLocation();
1253 }
1254
1255 /// Retrieve the receiver type to which this message is being directed.
1256 ///
1257 /// This routine cross-cuts all of the different kinds of message
1258 /// sends to determine what the underlying (statically known) type
1259 /// of the receiver will be; use \c getReceiverKind() to determine
1260 /// whether the message is a class or an instance method, whether it
1261 /// is a send to super or not, etc.
1262 ///
1263 /// \returns The type of the receiver.
1264 QualType getReceiverType() const;
1265
1266 /// Retrieve the Objective-C interface to which this message
1267 /// is being directed, if known.
1268 ///
1269 /// This routine cross-cuts all of the different kinds of message
1270 /// sends to determine what the underlying (statically known) type
1271 /// of the receiver will be; use \c getReceiverKind() to determine
1272 /// whether the message is a class or an instance method, whether it
1273 /// is a send to super or not, etc.
1274 ///
1275 /// \returns The Objective-C interface if known, otherwise nullptr.
1276 ObjCInterfaceDecl *getReceiverInterface() const;
1277
1278 /// Retrieve the type referred to by 'super'.
1279 ///
1280 /// The returned type will either be an ObjCInterfaceType (for an
1281 /// class message to super) or an ObjCObjectPointerType that refers
1282 /// to a class (for an instance message to super);
1283 QualType getSuperType() const {
1284 if (getReceiverKind() == SuperInstance || getReceiverKind() == SuperClass)
1285 return QualType::getFromOpaquePtr(getReceiverPointer());
1286
1287 return QualType();
1288 }
1289
1290 void setSuper(SourceLocation Loc, QualType T, bool IsInstanceSuper) {
1291 Kind = IsInstanceSuper? SuperInstance : SuperClass;
1292 SuperLoc = Loc;
1293 setReceiverPointer(T.getAsOpaquePtr());
1294 }
1295
1296 Selector getSelector() const;
1297
1298 void setSelector(Selector S) {
1299 HasMethod = false;
1300 SelectorOrMethod = reinterpret_cast<uintptr_t>(S.getAsOpaquePtr());
1301 }
1302
1303 const ObjCMethodDecl *getMethodDecl() const {
1304 if (HasMethod)
1305 return reinterpret_cast<const ObjCMethodDecl *>(SelectorOrMethod);
1306
1307 return nullptr;
1308 }
1309
1310 ObjCMethodDecl *getMethodDecl() {
1311 if (HasMethod)
1312 return reinterpret_cast<ObjCMethodDecl *>(SelectorOrMethod);
1313
1314 return nullptr;
1315 }
1316
1317 void setMethodDecl(ObjCMethodDecl *MD) {
1318 HasMethod = true;
1319 SelectorOrMethod = reinterpret_cast<uintptr_t>(MD);
1320 }
1321
1322 ObjCMethodFamily getMethodFamily() const {
1323 if (HasMethod) return getMethodDecl()->getMethodFamily();
1324 return getSelector().getMethodFamily();
1325 }
1326
1327 /// Return the number of actual arguments in this message,
1328 /// not counting the receiver.
1329 unsigned getNumArgs() const { return NumArgs; }
1330
1331 /// Retrieve the arguments to this message, not including the
1332 /// receiver.
1333 Expr **getArgs() {
1334 return reinterpret_cast<Expr **>(getTrailingObjects<void *>() + 1);
1335 }
1336 const Expr * const *getArgs() const {
1337 return reinterpret_cast<const Expr *const *>(getTrailingObjects<void *>() +
1338 1);
1339 }
1340
1341 /// getArg - Return the specified argument.
1342 Expr *getArg(unsigned Arg) {
1343 assert(Arg < NumArgs && "Arg access out of range!");
1344 return getArgs()[Arg];
1345 }
1346 const Expr *getArg(unsigned Arg) const {
1347 assert(Arg < NumArgs && "Arg access out of range!");
1348 return getArgs()[Arg];
1349 }
1350
1351 /// setArg - Set the specified argument.
1352 void setArg(unsigned Arg, Expr *ArgExpr) {
1353 assert(Arg < NumArgs && "Arg access out of range!");
1354 getArgs()[Arg] = ArgExpr;
1355 }
1356
1357 /// isDelegateInitCall - Answers whether this message send has been
1358 /// tagged as a "delegate init call", i.e. a call to a method in the
1359 /// -init family on self from within an -init method implementation.
1360 bool isDelegateInitCall() const { return IsDelegateInitCall; }
1361 void setDelegateInitCall(bool isDelegate) { IsDelegateInitCall = isDelegate; }
1362
1363 SourceLocation getLeftLoc() const { return LBracLoc; }
1364 SourceLocation getRightLoc() const { return RBracLoc; }
1365
1366 SourceLocation getSelectorStartLoc() const {
1367 if (isImplicit())
1368 return getBeginLoc();
1369 return getSelectorLoc(0);
1370 }
1371
1372 SourceLocation getSelectorLoc(unsigned Index) const {
1373 assert(Index < getNumSelectorLocs() && "Index out of range!");
1374 if (hasStandardSelLocs())
1375 return getStandardSelectorLoc(Index, getSelector(),
1376 getSelLocsKind() == SelLoc_StandardWithSpace,
1377 llvm::makeArrayRef(const_cast<Expr**>(getArgs()),
1378 getNumArgs()),
1379 RBracLoc);
1380 return getStoredSelLocs()[Index];
1381 }
1382
1383 void getSelectorLocs(SmallVectorImpl<SourceLocation> &SelLocs) const;
1384
1385 unsigned getNumSelectorLocs() const {
1386 if (isImplicit())
1387 return 0;
1388 Selector Sel = getSelector();
1389 if (Sel.isUnarySelector())
1390 return 1;
1391 return Sel.getNumArgs();
1392 }
1393
1394 void setSourceRange(SourceRange R) {
1395 LBracLoc = R.getBegin();
1396 RBracLoc = R.getEnd();
1397 }
1398
1399 SourceLocation getBeginLoc() const LLVM_READONLY { return LBracLoc; }
1400 SourceLocation getEndLoc() const LLVM_READONLY { return RBracLoc; }
1401
1402 // Iterators
1403 child_range children();
1404
1405 using arg_iterator = ExprIterator;
1406 using const_arg_iterator = ConstExprIterator;
1407
1408 llvm::iterator_range<arg_iterator> arguments() {
1409 return llvm::make_range(arg_begin(), arg_end());
1410 }
1411
1412 llvm::iterator_range<const_arg_iterator> arguments() const {
1413 return llvm::make_range(arg_begin(), arg_end());
1414 }
1415
1416 arg_iterator arg_begin() { return reinterpret_cast<Stmt **>(getArgs()); }
1417
1418 arg_iterator arg_end() {
1419 return reinterpret_cast<Stmt **>(getArgs() + NumArgs);
1420 }
1421
1422 const_arg_iterator arg_begin() const {
1423 return reinterpret_cast<Stmt const * const*>(getArgs());
1424 }
1425
1426 const_arg_iterator arg_end() const {
1427 return reinterpret_cast<Stmt const * const*>(getArgs() + NumArgs);
1428 }
1429
1430 static bool classof(const Stmt *T) {
1431 return T->getStmtClass() == ObjCMessageExprClass;
1432 }
1433};
1434
1435/// ObjCIsaExpr - Represent X->isa and X.isa when X is an ObjC 'id' type.
1436/// (similar in spirit to MemberExpr).
1437class ObjCIsaExpr : public Expr {
1438 /// Base - the expression for the base object pointer.
1439 Stmt *Base;
1440
1441 /// IsaMemberLoc - This is the location of the 'isa'.
1442 SourceLocation IsaMemberLoc;
1443
1444 /// OpLoc - This is the location of '.' or '->'
1445 SourceLocation OpLoc;
1446
1447 /// IsArrow - True if this is "X->F", false if this is "X.F".
1448 bool IsArrow;
1449
1450public:
1451 ObjCIsaExpr(Expr *base, bool isarrow, SourceLocation l, SourceLocation oploc,
1452 QualType ty)
1453 : Expr(ObjCIsaExprClass, ty, VK_LValue, OK_Ordinary,
1454 /*TypeDependent=*/false, base->isValueDependent(),
1455 base->isInstantiationDependent(),
1456 /*ContainsUnexpandedParameterPack=*/false),
1457 Base(base), IsaMemberLoc(l), OpLoc(oploc), IsArrow(isarrow) {}
1458
1459 /// Build an empty expression.
1460 explicit ObjCIsaExpr(EmptyShell Empty) : Expr(ObjCIsaExprClass, Empty) {}
1461
1462 void setBase(Expr *E) { Base = E; }
1463 Expr *getBase() const { return cast<Expr>(Base); }
1464
1465 bool isArrow() const { return IsArrow; }
1466 void setArrow(bool A) { IsArrow = A; }
1467
1468 /// getMemberLoc - Return the location of the "member", in X->F, it is the
1469 /// location of 'F'.
1470 SourceLocation getIsaMemberLoc() const { return IsaMemberLoc; }
1471 void setIsaMemberLoc(SourceLocation L) { IsaMemberLoc = L; }
1472
1473 SourceLocation getOpLoc() const { return OpLoc; }
1474 void setOpLoc(SourceLocation L) { OpLoc = L; }
1475
1476 SourceLocation getBeginLoc() const LLVM_READONLY {
1477 return getBase()->getBeginLoc();
1478 }
1479
1480 SourceLocation getBaseLocEnd() const LLVM_READONLY {
1481 return getBase()->getEndLoc();
1482 }
1483
1484 SourceLocation getEndLoc() const LLVM_READONLY { return IsaMemberLoc; }
1485
1486 SourceLocation getExprLoc() const LLVM_READONLY { return IsaMemberLoc; }
1487
1488 // Iterators
1489 child_range children() { return child_range(&Base, &Base+1); }
1490
1491 static bool classof(const Stmt *T) {
1492 return T->getStmtClass() == ObjCIsaExprClass;
1493 }
1494};
1495
1496/// ObjCIndirectCopyRestoreExpr - Represents the passing of a function
1497/// argument by indirect copy-restore in ARC. This is used to support
1498/// passing indirect arguments with the wrong lifetime, e.g. when
1499/// passing the address of a __strong local variable to an 'out'
1500/// parameter. This expression kind is only valid in an "argument"
1501/// position to some sort of call expression.
1502///
1503/// The parameter must have type 'pointer to T', and the argument must
1504/// have type 'pointer to U', where T and U agree except possibly in
1505/// qualification. If the argument value is null, then a null pointer
1506/// is passed; otherwise it points to an object A, and:
1507/// 1. A temporary object B of type T is initialized, either by
1508/// zero-initialization (used when initializing an 'out' parameter)
1509/// or copy-initialization (used when initializing an 'inout'
1510/// parameter).
1511/// 2. The address of the temporary is passed to the function.
1512/// 3. If the call completes normally, A is move-assigned from B.
1513/// 4. Finally, A is destroyed immediately.
1514///
1515/// Currently 'T' must be a retainable object lifetime and must be
1516/// __autoreleasing; this qualifier is ignored when initializing
1517/// the value.
1518class ObjCIndirectCopyRestoreExpr : public Expr {
1519 friend class ASTReader;
1520 friend class ASTStmtReader;
1521
1522 Stmt *Operand;
1523
1524 // unsigned ObjCIndirectCopyRestoreBits.ShouldCopy : 1;
1525
1526 explicit ObjCIndirectCopyRestoreExpr(EmptyShell Empty)
1527 : Expr(ObjCIndirectCopyRestoreExprClass, Empty) {}
1528
1529 void setShouldCopy(bool shouldCopy) {
1530 ObjCIndirectCopyRestoreExprBits.ShouldCopy = shouldCopy;
1531 }
1532
1533public:
1534 ObjCIndirectCopyRestoreExpr(Expr *operand, QualType type, bool shouldCopy)
1535 : Expr(ObjCIndirectCopyRestoreExprClass, type, VK_LValue, OK_Ordinary,
1536 operand->isTypeDependent(), operand->isValueDependent(),
1537 operand->isInstantiationDependent(),
1538 operand->containsUnexpandedParameterPack()),
1539 Operand(operand) {
1540 setShouldCopy(shouldCopy);
1541 }
1542
1543 Expr *getSubExpr() { return cast<Expr>(Operand); }
1544 const Expr *getSubExpr() const { return cast<Expr>(Operand); }
1545
1546 /// shouldCopy - True if we should do the 'copy' part of the
1547 /// copy-restore. If false, the temporary will be zero-initialized.
1548 bool shouldCopy() const { return ObjCIndirectCopyRestoreExprBits.ShouldCopy; }
1549
1550 child_range children() { return child_range(&Operand, &Operand+1); }
1551
1552 // Source locations are determined by the subexpression.
1553 SourceLocation getBeginLoc() const LLVM_READONLY {
1554 return Operand->getBeginLoc();
1555 }
1556 SourceLocation getEndLoc() const LLVM_READONLY {
1557 return Operand->getEndLoc();
1558 }
1559
1560 SourceLocation getExprLoc() const LLVM_READONLY {
1561 return getSubExpr()->getExprLoc();
1562 }
1563
1564 static bool classof(const Stmt *s) {
1565 return s->getStmtClass() == ObjCIndirectCopyRestoreExprClass;
1566 }
1567};
1568
1569/// An Objective-C "bridged" cast expression, which casts between
1570/// Objective-C pointers and C pointers, transferring ownership in the process.
1571///
1572/// \code
1573/// NSString *str = (__bridge_transfer NSString *)CFCreateString();
1574/// \endcode
1575class ObjCBridgedCastExpr final
1576 : public ExplicitCastExpr,
1577 private llvm::TrailingObjects<ObjCBridgedCastExpr, CXXBaseSpecifier *> {
1578 friend class ASTStmtReader;
1579 friend class ASTStmtWriter;
1580 friend class CastExpr;
1581 friend TrailingObjects;
1582
1583 SourceLocation LParenLoc;
1584 SourceLocation BridgeKeywordLoc;
1585 unsigned Kind : 2;
1586
1587public:
1588 ObjCBridgedCastExpr(SourceLocation LParenLoc, ObjCBridgeCastKind Kind,
1589 CastKind CK, SourceLocation BridgeKeywordLoc,
1590 TypeSourceInfo *TSInfo, Expr *Operand)
1591 : ExplicitCastExpr(ObjCBridgedCastExprClass, TSInfo->getType(), VK_RValue,
1592 CK, Operand, 0, TSInfo),
1593 LParenLoc(LParenLoc), BridgeKeywordLoc(BridgeKeywordLoc), Kind(Kind) {}
1594
1595 /// Construct an empty Objective-C bridged cast.
1596 explicit ObjCBridgedCastExpr(EmptyShell Shell)
1597 : ExplicitCastExpr(ObjCBridgedCastExprClass, Shell, 0) {}
1598
1599 SourceLocation getLParenLoc() const { return LParenLoc; }
1600
1601 /// Determine which kind of bridge is being performed via this cast.
1602 ObjCBridgeCastKind getBridgeKind() const {
1603 return static_cast<ObjCBridgeCastKind>(Kind);
1604 }
1605
1606 /// Retrieve the kind of bridge being performed as a string.
1607 StringRef getBridgeKindName() const;
1608
1609 /// The location of the bridge keyword.
1610 SourceLocation getBridgeKeywordLoc() const { return BridgeKeywordLoc; }
1611
1612 SourceLocation getBeginLoc() const LLVM_READONLY { return LParenLoc; }
1613
1614 SourceLocation getEndLoc() const LLVM_READONLY {
1615 return getSubExpr()->getEndLoc();
1616 }
1617
1618 static bool classof(const Stmt *T) {
1619 return T->getStmtClass() == ObjCBridgedCastExprClass;
1620 }
1621};
1622
1623/// A runtime availability query.
1624///
1625/// There are 2 ways to spell this node:
1626/// \code
1627/// @available(macos 10.10, ios 8, *); // Objective-C
1628/// __builtin_available(macos 10.10, ios 8, *); // C, C++, and Objective-C
1629/// \endcode
1630///
1631/// Note that we only need to keep track of one \c VersionTuple here, which is
1632/// the one that corresponds to the current deployment target. This is meant to
1633/// be used in the condition of an \c if, but it is also usable as top level
1634/// expressions.
1635///
1636class ObjCAvailabilityCheckExpr : public Expr {
1637 friend class ASTStmtReader;
1638
1639 VersionTuple VersionToCheck;
1640 SourceLocation AtLoc, RParen;
1641
1642public:
1643 ObjCAvailabilityCheckExpr(VersionTuple VersionToCheck, SourceLocation AtLoc,
1644 SourceLocation RParen, QualType Ty)
1645 : Expr(ObjCAvailabilityCheckExprClass, Ty, VK_RValue, OK_Ordinary, false,
1646 false, false, false),
1647 VersionToCheck(VersionToCheck), AtLoc(AtLoc), RParen(RParen) {}
1648
1649 explicit ObjCAvailabilityCheckExpr(EmptyShell Shell)
1650 : Expr(ObjCAvailabilityCheckExprClass, Shell) {}
1651
1652 SourceLocation getBeginLoc() const { return AtLoc; }
1653 SourceLocation getEndLoc() const { return RParen; }
1654 SourceRange getSourceRange() const { return {AtLoc, RParen}; }
1655
1656 /// This may be '*', in which case this should fold to true.
1657 bool hasVersion() const { return !VersionToCheck.empty(); }
1658 VersionTuple getVersion() { return VersionToCheck; }
1659
1660 child_range children() {
1661 return child_range(child_iterator(), child_iterator());
1662 }
1663
1664 static bool classof(const Stmt *T) {
1665 return T->getStmtClass() == ObjCAvailabilityCheckExprClass;
1666 }
1667};
1668
1669} // namespace clang
1670
1671#endif // LLVM_CLANG_AST_EXPROBJC_H
1672