Coverage Report

Created: 2019-07-24 05:18

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