Coverage Report

Created: 2020-09-19 12:23

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