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