Coverage Report

Created: 2018-07-19 20:53

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