Coverage Report

Created: 2019-02-23 12:57

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