Coverage Report

Created: 2018-09-23 03:40

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