- //===- ExprObjC.h - Classes for representing ObjC expressions ---*- C++ -*-===// 
- // 
- // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 
- // See https://llvm.org/LICENSE.txt for license information. 
- // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 
- // 
- //===----------------------------------------------------------------------===// 
- // 
- //  This file defines the ExprObjC interface and subclasses. 
- // 
- //===----------------------------------------------------------------------===// 
-   
- #ifndef LLVM_CLANG_AST_EXPROBJC_H 
- #define LLVM_CLANG_AST_EXPROBJC_H 
-   
- #include "clang/AST/ComputeDependence.h" 
- #include "clang/AST/Decl.h" 
- #include "clang/AST/DeclObjC.h" 
- #include "clang/AST/DependenceFlags.h" 
- #include "clang/AST/Expr.h" 
- #include "clang/AST/OperationKinds.h" 
- #include "clang/AST/SelectorLocationsKind.h" 
- #include "clang/AST/Stmt.h" 
- #include "clang/AST/Type.h" 
- #include "clang/Basic/IdentifierTable.h" 
- #include "clang/Basic/LLVM.h" 
- #include "clang/Basic/SourceLocation.h" 
- #include "clang/Basic/Specifiers.h" 
- #include "llvm/ADT/ArrayRef.h" 
- #include "llvm/ADT/PointerIntPair.h" 
- #include "llvm/ADT/PointerUnion.h" 
- #include "llvm/ADT/StringRef.h" 
- #include "llvm/ADT/iterator_range.h" 
- #include "llvm/Support/Casting.h" 
- #include "llvm/Support/Compiler.h" 
- #include "llvm/Support/TrailingObjects.h" 
- #include "llvm/Support/VersionTuple.h" 
- #include "llvm/Support/type_traits.h" 
- #include <cassert> 
- #include <cstddef> 
- #include <cstdint> 
- #include <optional> 
-   
- namespace clang { 
-   
- class ASTContext; 
- class CXXBaseSpecifier; 
-   
- /// ObjCStringLiteral, used for Objective-C string literals 
- /// i.e. @"foo". 
- class ObjCStringLiteral : public Expr { 
-   Stmt *String; 
-   SourceLocation AtLoc; 
-   
- public: 
-   ObjCStringLiteral(StringLiteral *SL, QualType T, SourceLocation L) 
-       : Expr(ObjCStringLiteralClass, T, VK_PRValue, OK_Ordinary), String(SL), 
-         AtLoc(L) { 
-     setDependence(ExprDependence::None); 
-   } 
-   explicit ObjCStringLiteral(EmptyShell Empty) 
-       : Expr(ObjCStringLiteralClass, Empty) {} 
-   
-   StringLiteral *getString() { return cast<StringLiteral>(String); } 
-   const StringLiteral *getString() const { return cast<StringLiteral>(String); } 
-   void setString(StringLiteral *S) { String = S; } 
-   
-   SourceLocation getAtLoc() const { return AtLoc; } 
-   void setAtLoc(SourceLocation L) { AtLoc = L; } 
-   
-   SourceLocation getBeginLoc() const LLVM_READONLY { return AtLoc; } 
-   SourceLocation getEndLoc() const LLVM_READONLY { return String->getEndLoc(); } 
-   
-   // Iterators 
-   child_range children() { return child_range(&String, &String+1); } 
-   
-   const_child_range children() const { 
-     return const_child_range(&String, &String + 1); 
-   } 
-   
-   static bool classof(const Stmt *T) { 
-     return T->getStmtClass() == ObjCStringLiteralClass; 
-   } 
- }; 
-   
- /// ObjCBoolLiteralExpr - Objective-C Boolean Literal. 
- class ObjCBoolLiteralExpr : public Expr { 
-   bool Value; 
-   SourceLocation Loc; 
-   
- public: 
-   ObjCBoolLiteralExpr(bool val, QualType Ty, SourceLocation l) 
-       : Expr(ObjCBoolLiteralExprClass, Ty, VK_PRValue, OK_Ordinary), Value(val), 
-         Loc(l) { 
-     setDependence(ExprDependence::None); 
-   } 
-   explicit ObjCBoolLiteralExpr(EmptyShell Empty) 
-       : Expr(ObjCBoolLiteralExprClass, Empty) {} 
-   
-   bool getValue() const { return Value; } 
-   void setValue(bool V) { Value = V; } 
-   
-   SourceLocation getBeginLoc() const LLVM_READONLY { return Loc; } 
-   SourceLocation getEndLoc() const LLVM_READONLY { return Loc; } 
-   
-   SourceLocation getLocation() const { return Loc; } 
-   void setLocation(SourceLocation L) { Loc = L; } 
-   
-   // Iterators 
-   child_range children() { 
-     return child_range(child_iterator(), child_iterator()); 
-   } 
-   
-   const_child_range children() const { 
-     return const_child_range(const_child_iterator(), const_child_iterator()); 
-   } 
-   
-   static bool classof(const Stmt *T) { 
-     return T->getStmtClass() == ObjCBoolLiteralExprClass; 
-   } 
- }; 
-   
- /// ObjCBoxedExpr - used for generalized expression boxing. 
- /// as in: @(strdup("hello world")), @(random()) or @(view.frame) 
- /// Also used for boxing non-parenthesized numeric literals; 
- /// as in: @42 or \@true (c++/objc++) or \@__objc_yes (c/objc). 
- class ObjCBoxedExpr : public Expr { 
-   Stmt *SubExpr; 
-   ObjCMethodDecl *BoxingMethod; 
-   SourceRange Range; 
-   
- public: 
-   friend class ASTStmtReader; 
-   
-   ObjCBoxedExpr(Expr *E, QualType T, ObjCMethodDecl *method, SourceRange R) 
-       : Expr(ObjCBoxedExprClass, T, VK_PRValue, OK_Ordinary), SubExpr(E), 
-         BoxingMethod(method), Range(R) { 
-     setDependence(computeDependence(this)); 
-   } 
-   explicit ObjCBoxedExpr(EmptyShell Empty) 
-       : Expr(ObjCBoxedExprClass, Empty) {} 
-   
-   Expr *getSubExpr() { return cast<Expr>(SubExpr); } 
-   const Expr *getSubExpr() const { return cast<Expr>(SubExpr); } 
-   
-   ObjCMethodDecl *getBoxingMethod() const { 
-     return BoxingMethod; 
-   } 
-   
-   // Indicates whether this boxed expression can be emitted as a compile-time 
-   // constant. 
-   bool isExpressibleAsConstantInitializer() const { 
-     return !BoxingMethod && SubExpr; 
-   } 
-   
-   SourceLocation getAtLoc() const { return Range.getBegin(); } 
-   
-   SourceLocation getBeginLoc() const LLVM_READONLY { return Range.getBegin(); } 
-   SourceLocation getEndLoc() const LLVM_READONLY { return Range.getEnd(); } 
-   
-   SourceRange getSourceRange() const LLVM_READONLY { 
-     return Range; 
-   } 
-   
-   // Iterators 
-   child_range children() { return child_range(&SubExpr, &SubExpr+1); } 
-   
-   const_child_range children() const { 
-     return const_child_range(&SubExpr, &SubExpr + 1); 
-   } 
-   
-   using const_arg_iterator = ConstExprIterator; 
-   
-   const_arg_iterator arg_begin() const { 
-     return reinterpret_cast<Stmt const * const*>(&SubExpr); 
-   } 
-   
-   const_arg_iterator arg_end() const { 
-     return reinterpret_cast<Stmt const * const*>(&SubExpr + 1); 
-   } 
-   
-   static bool classof(const Stmt *T) { 
-     return T->getStmtClass() == ObjCBoxedExprClass; 
-   } 
- }; 
-   
- /// ObjCArrayLiteral - used for objective-c array containers; as in: 
- /// @[@"Hello", NSApp, [NSNumber numberWithInt:42]]; 
- class ObjCArrayLiteral final 
-     : public Expr, 
-       private llvm::TrailingObjects<ObjCArrayLiteral, Expr *> { 
-   unsigned NumElements; 
-   SourceRange Range; 
-   ObjCMethodDecl *ArrayWithObjectsMethod; 
-   
-   ObjCArrayLiteral(ArrayRef<Expr *> Elements, 
-                    QualType T, ObjCMethodDecl * Method, 
-                    SourceRange SR); 
-   
-   explicit ObjCArrayLiteral(EmptyShell Empty, unsigned NumElements) 
-       : Expr(ObjCArrayLiteralClass, Empty), NumElements(NumElements) {} 
-   
- public: 
-   friend class ASTStmtReader; 
-   friend TrailingObjects; 
-   
-   static ObjCArrayLiteral *Create(const ASTContext &C, 
-                                   ArrayRef<Expr *> Elements, 
-                                   QualType T, ObjCMethodDecl * Method, 
-                                   SourceRange SR); 
-   
-   static ObjCArrayLiteral *CreateEmpty(const ASTContext &C, 
-                                        unsigned NumElements); 
-   
-   SourceLocation getBeginLoc() const LLVM_READONLY { return Range.getBegin(); } 
-   SourceLocation getEndLoc() const LLVM_READONLY { return Range.getEnd(); } 
-   SourceRange getSourceRange() const LLVM_READONLY { return Range; } 
-   
-   /// Retrieve elements of array of literals. 
-   Expr **getElements() { return getTrailingObjects<Expr *>(); } 
-   
-   /// Retrieve elements of array of literals. 
-   const Expr * const *getElements() const { 
-     return getTrailingObjects<Expr *>(); 
-   } 
-   
-   /// getNumElements - Return number of elements of objective-c array literal. 
-   unsigned getNumElements() const { return NumElements; } 
-   
-   /// getElement - Return the Element at the specified index. 
-   Expr *getElement(unsigned Index) { 
-     assert((Index < NumElements) && "Arg access out of range!"); 
-     return getElements()[Index]; 
-   } 
-   const Expr *getElement(unsigned Index) const { 
-     assert((Index < NumElements) && "Arg access out of range!"); 
-     return getElements()[Index]; 
-   } 
-   
-   ObjCMethodDecl *getArrayWithObjectsMethod() const { 
-     return ArrayWithObjectsMethod; 
-   } 
-   
-   // Iterators 
-   child_range children() { 
-     return child_range(reinterpret_cast<Stmt **>(getElements()), 
-                        reinterpret_cast<Stmt **>(getElements()) + NumElements); 
-   } 
-   
-   const_child_range children() const { 
-     auto Children = const_cast<ObjCArrayLiteral *>(this)->children(); 
-     return const_child_range(Children.begin(), Children.end()); 
-   } 
-   
-   static bool classof(const Stmt *T) { 
-       return T->getStmtClass() == ObjCArrayLiteralClass; 
-   } 
- }; 
-   
- /// An element in an Objective-C dictionary literal. 
- /// 
- struct ObjCDictionaryElement { 
-   /// The key for the dictionary element. 
-   Expr *Key; 
-   
-   /// The value of the dictionary element. 
-   Expr *Value; 
-   
-   /// The location of the ellipsis, if this is a pack expansion. 
-   SourceLocation EllipsisLoc; 
-   
-   /// The number of elements this pack expansion will expand to, if 
-   /// this is a pack expansion and is known. 
-   std::optional<unsigned> NumExpansions; 
-   
-   /// Determines whether this dictionary element is a pack expansion. 
-   bool isPackExpansion() const { return EllipsisLoc.isValid(); } 
- }; 
-   
- } // namespace clang 
-   
- namespace clang { 
-   
- /// Internal struct for storing Key/value pair. 
- struct ObjCDictionaryLiteral_KeyValuePair { 
-   Expr *Key; 
-   Expr *Value; 
- }; 
-   
- /// Internal struct to describes an element that is a pack 
- /// expansion, used if any of the elements in the dictionary literal 
- /// are pack expansions. 
- struct ObjCDictionaryLiteral_ExpansionData { 
-   /// The location of the ellipsis, if this element is a pack 
-   /// expansion. 
-   SourceLocation EllipsisLoc; 
-   
-   /// If non-zero, the number of elements that this pack 
-   /// expansion will expand to (+1). 
-   unsigned NumExpansionsPlusOne; 
- }; 
-   
- /// ObjCDictionaryLiteral - AST node to represent objective-c dictionary 
- /// literals; as in:  @{@"name" : NSUserName(), @"date" : [NSDate date] }; 
- class ObjCDictionaryLiteral final 
-     : public Expr, 
-       private llvm::TrailingObjects<ObjCDictionaryLiteral, 
-                                     ObjCDictionaryLiteral_KeyValuePair, 
-                                     ObjCDictionaryLiteral_ExpansionData> { 
-   /// The number of elements in this dictionary literal. 
-   unsigned NumElements : 31; 
-   
-   /// Determine whether this dictionary literal has any pack expansions. 
-   /// 
-   /// If the dictionary literal has pack expansions, then there will 
-   /// be an array of pack expansion data following the array of 
-   /// key/value pairs, which provide the locations of the ellipses (if 
-   /// any) and number of elements in the expansion (if known). If 
-   /// there are no pack expansions, we optimize away this storage. 
-   unsigned HasPackExpansions : 1; 
-   
-   SourceRange Range; 
-   ObjCMethodDecl *DictWithObjectsMethod; 
-   
-   using KeyValuePair = ObjCDictionaryLiteral_KeyValuePair; 
-   using ExpansionData = ObjCDictionaryLiteral_ExpansionData; 
-   
-   ObjCDictionaryLiteral(ArrayRef<ObjCDictionaryElement> VK, 
-                         bool HasPackExpansions, 
-                         QualType T, ObjCMethodDecl *method, 
-                         SourceRange SR); 
-   
-   explicit ObjCDictionaryLiteral(EmptyShell Empty, unsigned NumElements, 
-                                  bool HasPackExpansions) 
-       : Expr(ObjCDictionaryLiteralClass, Empty), NumElements(NumElements), 
-         HasPackExpansions(HasPackExpansions) {} 
-   
-   size_t numTrailingObjects(OverloadToken<KeyValuePair>) const { 
-     return NumElements; 
-   } 
-   
- public: 
-   friend class ASTStmtReader; 
-   friend class ASTStmtWriter; 
-   friend TrailingObjects; 
-   
-   static ObjCDictionaryLiteral *Create(const ASTContext &C, 
-                                        ArrayRef<ObjCDictionaryElement> VK, 
-                                        bool HasPackExpansions, 
-                                        QualType T, ObjCMethodDecl *method, 
-                                        SourceRange SR); 
-   
-   static ObjCDictionaryLiteral *CreateEmpty(const ASTContext &C, 
-                                             unsigned NumElements, 
-                                             bool HasPackExpansions); 
-   
-   /// getNumElements - Return number of elements of objective-c dictionary 
-   /// literal. 
-   unsigned getNumElements() const { return NumElements; } 
-   
-   ObjCDictionaryElement getKeyValueElement(unsigned Index) const { 
-     assert((Index < NumElements) && "Arg access out of range!"); 
-     const KeyValuePair &KV = getTrailingObjects<KeyValuePair>()[Index]; 
-     ObjCDictionaryElement Result = {KV.Key, KV.Value, SourceLocation(), 
-                                     std::nullopt}; 
-     if (HasPackExpansions) { 
-       const ExpansionData &Expansion = 
-           getTrailingObjects<ExpansionData>()[Index]; 
-       Result.EllipsisLoc = Expansion.EllipsisLoc; 
-       if (Expansion.NumExpansionsPlusOne > 0) 
-         Result.NumExpansions = Expansion.NumExpansionsPlusOne - 1; 
-     } 
-     return Result; 
-   } 
-   
-   ObjCMethodDecl *getDictWithObjectsMethod() const { 
-     return DictWithObjectsMethod; 
-   } 
-   
-   SourceLocation getBeginLoc() const LLVM_READONLY { return Range.getBegin(); } 
-   SourceLocation getEndLoc() const LLVM_READONLY { return Range.getEnd(); } 
-   SourceRange getSourceRange() const LLVM_READONLY { return Range; } 
-   
-   // Iterators 
-   child_range children() { 
-     // Note: we're taking advantage of the layout of the KeyValuePair struct 
-     // here. If that struct changes, this code will need to change as well. 
-     static_assert(sizeof(KeyValuePair) == sizeof(Stmt *) * 2, 
-                   "KeyValuePair is expected size"); 
-     return child_range( 
-         reinterpret_cast<Stmt **>(getTrailingObjects<KeyValuePair>()), 
-         reinterpret_cast<Stmt **>(getTrailingObjects<KeyValuePair>()) + 
-             NumElements * 2); 
-   } 
-   
-   const_child_range children() const { 
-     auto Children = const_cast<ObjCDictionaryLiteral *>(this)->children(); 
-     return const_child_range(Children.begin(), Children.end()); 
-   } 
-   
-   static bool classof(const Stmt *T) { 
-     return T->getStmtClass() == ObjCDictionaryLiteralClass; 
-   } 
- }; 
-   
- /// ObjCEncodeExpr, used for \@encode in Objective-C.  \@encode has the same 
- /// type and behavior as StringLiteral except that the string initializer is 
- /// obtained from ASTContext with the encoding type as an argument. 
- class ObjCEncodeExpr : public Expr { 
-   TypeSourceInfo *EncodedType; 
-   SourceLocation AtLoc, RParenLoc; 
-   
- public: 
-   ObjCEncodeExpr(QualType T, TypeSourceInfo *EncodedType, SourceLocation at, 
-                  SourceLocation rp) 
-       : Expr(ObjCEncodeExprClass, T, VK_LValue, OK_Ordinary), 
-         EncodedType(EncodedType), AtLoc(at), RParenLoc(rp) { 
-     setDependence(computeDependence(this)); 
-   } 
-   
-   explicit ObjCEncodeExpr(EmptyShell Empty) : Expr(ObjCEncodeExprClass, Empty){} 
-   
-   SourceLocation getAtLoc() const { return AtLoc; } 
-   void setAtLoc(SourceLocation L) { AtLoc = L; } 
-   SourceLocation getRParenLoc() const { return RParenLoc; } 
-   void setRParenLoc(SourceLocation L) { RParenLoc = L; } 
-   
-   QualType getEncodedType() const { return EncodedType->getType(); } 
-   
-   TypeSourceInfo *getEncodedTypeSourceInfo() const { return EncodedType; } 
-   
-   void setEncodedTypeSourceInfo(TypeSourceInfo *EncType) { 
-     EncodedType = EncType; 
-   } 
-   
-   SourceLocation getBeginLoc() const LLVM_READONLY { return AtLoc; } 
-   SourceLocation getEndLoc() const LLVM_READONLY { return RParenLoc; } 
-   
-   // Iterators 
-   child_range children() { 
-     return child_range(child_iterator(), child_iterator()); 
-   } 
-   
-   const_child_range children() const { 
-     return const_child_range(const_child_iterator(), const_child_iterator()); 
-   } 
-   
-   static bool classof(const Stmt *T) { 
-     return T->getStmtClass() == ObjCEncodeExprClass; 
-   } 
- }; 
-   
- /// ObjCSelectorExpr used for \@selector in Objective-C. 
- class ObjCSelectorExpr : public Expr { 
-   Selector SelName; 
-   SourceLocation AtLoc, RParenLoc; 
-   
- public: 
-   ObjCSelectorExpr(QualType T, Selector selInfo, SourceLocation at, 
-                    SourceLocation rp) 
-       : Expr(ObjCSelectorExprClass, T, VK_PRValue, OK_Ordinary), 
-         SelName(selInfo), AtLoc(at), RParenLoc(rp) { 
-     setDependence(ExprDependence::None); 
-   } 
-   explicit ObjCSelectorExpr(EmptyShell Empty) 
-       : Expr(ObjCSelectorExprClass, Empty) {} 
-   
-   Selector getSelector() const { return SelName; } 
-   void setSelector(Selector S) { SelName = S; } 
-   
-   SourceLocation getAtLoc() const { return AtLoc; } 
-   SourceLocation getRParenLoc() const { return RParenLoc; } 
-   void setAtLoc(SourceLocation L) { AtLoc = L; } 
-   void setRParenLoc(SourceLocation L) { RParenLoc = L; } 
-   
-   SourceLocation getBeginLoc() const LLVM_READONLY { return AtLoc; } 
-   SourceLocation getEndLoc() const LLVM_READONLY { return RParenLoc; } 
-   
-   /// getNumArgs - Return the number of actual arguments to this call. 
-   unsigned getNumArgs() const { return SelName.getNumArgs(); } 
-   
-   // Iterators 
-   child_range children() { 
-     return child_range(child_iterator(), child_iterator()); 
-   } 
-   
-   const_child_range children() const { 
-     return const_child_range(const_child_iterator(), const_child_iterator()); 
-   } 
-   
-   static bool classof(const Stmt *T) { 
-     return T->getStmtClass() == ObjCSelectorExprClass; 
-   } 
- }; 
-   
- /// ObjCProtocolExpr used for protocol expression in Objective-C. 
- /// 
- /// This is used as: \@protocol(foo), as in: 
- /// \code 
- ///   [obj conformsToProtocol:@protocol(foo)] 
- /// \endcode 
- /// 
- /// The return type is "Protocol*". 
- class ObjCProtocolExpr : public Expr { 
-   ObjCProtocolDecl *TheProtocol; 
-   SourceLocation AtLoc, ProtoLoc, RParenLoc; 
-   
- public: 
-   friend class ASTStmtReader; 
-   friend class ASTStmtWriter; 
-   
-   ObjCProtocolExpr(QualType T, ObjCProtocolDecl *protocol, SourceLocation at, 
-                    SourceLocation protoLoc, SourceLocation rp) 
-       : Expr(ObjCProtocolExprClass, T, VK_PRValue, OK_Ordinary), 
-         TheProtocol(protocol), AtLoc(at), ProtoLoc(protoLoc), RParenLoc(rp) { 
-     setDependence(ExprDependence::None); 
-   } 
-   explicit ObjCProtocolExpr(EmptyShell Empty) 
-       : Expr(ObjCProtocolExprClass, Empty) {} 
-   
-   ObjCProtocolDecl *getProtocol() const { return TheProtocol; } 
-   void setProtocol(ObjCProtocolDecl *P) { TheProtocol = P; } 
-   
-   SourceLocation getProtocolIdLoc() const { return ProtoLoc; } 
-   SourceLocation getAtLoc() const { return AtLoc; } 
-   SourceLocation getRParenLoc() const { return RParenLoc; } 
-   void setAtLoc(SourceLocation L) { AtLoc = L; } 
-   void setRParenLoc(SourceLocation L) { RParenLoc = L; } 
-   
-   SourceLocation getBeginLoc() const LLVM_READONLY { return AtLoc; } 
-   SourceLocation getEndLoc() const LLVM_READONLY { return RParenLoc; } 
-   
-   // Iterators 
-   child_range children() { 
-     return child_range(child_iterator(), child_iterator()); 
-   } 
-   
-   const_child_range children() const { 
-     return const_child_range(const_child_iterator(), const_child_iterator()); 
-   } 
-   
-   static bool classof(const Stmt *T) { 
-     return T->getStmtClass() == ObjCProtocolExprClass; 
-   } 
- }; 
-   
- /// ObjCIvarRefExpr - A reference to an ObjC instance variable. 
- class ObjCIvarRefExpr : public Expr { 
-   ObjCIvarDecl *D; 
-   Stmt *Base; 
-   SourceLocation Loc; 
-   
-   /// OpLoc - This is the location of '.' or '->' 
-   SourceLocation OpLoc; 
-   
-   // True if this is "X->F", false if this is "X.F". 
-   bool IsArrow : 1; 
-   
-   // True if ivar reference has no base (self assumed). 
-   bool IsFreeIvar : 1; 
-   
- public: 
-   ObjCIvarRefExpr(ObjCIvarDecl *d, QualType t, SourceLocation l, 
-                   SourceLocation oploc, Expr *base, bool arrow = false, 
-                   bool freeIvar = false) 
-       : Expr(ObjCIvarRefExprClass, t, VK_LValue, 
-              d->isBitField() ? OK_BitField : OK_Ordinary), 
-         D(d), Base(base), Loc(l), OpLoc(oploc), IsArrow(arrow), 
-         IsFreeIvar(freeIvar) { 
-     setDependence(computeDependence(this)); 
-   } 
-   
-   explicit ObjCIvarRefExpr(EmptyShell Empty) 
-       : Expr(ObjCIvarRefExprClass, Empty) {} 
-   
-   ObjCIvarDecl *getDecl() { return D; } 
-   const ObjCIvarDecl *getDecl() const { return D; } 
-   void setDecl(ObjCIvarDecl *d) { D = d; } 
-   
-   const Expr *getBase() const { return cast<Expr>(Base); } 
-   Expr *getBase() { return cast<Expr>(Base); } 
-   void setBase(Expr * base) { Base = base; } 
-   
-   bool isArrow() const { return IsArrow; } 
-   bool isFreeIvar() const { return IsFreeIvar; } 
-   void setIsArrow(bool A) { IsArrow = A; } 
-   void setIsFreeIvar(bool A) { IsFreeIvar = A; } 
-   
-   SourceLocation getLocation() const { return Loc; } 
-   void setLocation(SourceLocation L) { Loc = L; } 
-   
-   SourceLocation getBeginLoc() const LLVM_READONLY { 
-     return isFreeIvar() ? Loc : getBase()->getBeginLoc(); 
-   } 
-   SourceLocation getEndLoc() const LLVM_READONLY { return Loc; } 
-   
-   SourceLocation getOpLoc() const { return OpLoc; } 
-   void setOpLoc(SourceLocation L) { OpLoc = L; } 
-   
-   // Iterators 
-   child_range children() { return child_range(&Base, &Base+1); } 
-   
-   const_child_range children() const { 
-     return const_child_range(&Base, &Base + 1); 
-   } 
-   
-   static bool classof(const Stmt *T) { 
-     return T->getStmtClass() == ObjCIvarRefExprClass; 
-   } 
- }; 
-   
- /// ObjCPropertyRefExpr - A dot-syntax expression to access an ObjC 
- /// property. 
- class ObjCPropertyRefExpr : public Expr { 
- private: 
-   /// If the bool is true, this is an implicit property reference; the 
-   /// pointer is an (optional) ObjCMethodDecl and Setter may be set. 
-   /// if the bool is false, this is an explicit property reference; 
-   /// the pointer is an ObjCPropertyDecl and Setter is always null. 
-   llvm::PointerIntPair<NamedDecl *, 1, bool> PropertyOrGetter; 
-   
-   /// Indicates whether the property reference will result in a message 
-   /// to the getter, the setter, or both. 
-   /// This applies to both implicit and explicit property references. 
-   enum MethodRefFlags { 
-     MethodRef_None = 0, 
-     MethodRef_Getter = 0x1, 
-     MethodRef_Setter = 0x2 
-   }; 
-   
-   /// Contains the Setter method pointer and MethodRefFlags bit flags. 
-   llvm::PointerIntPair<ObjCMethodDecl *, 2, unsigned> SetterAndMethodRefFlags; 
-   
-   // FIXME: Maybe we should store the property identifier here, 
-   // because it's not rederivable from the other data when there's an 
-   // implicit property with no getter (because the 'foo' -> 'setFoo:' 
-   // transformation is lossy on the first character). 
-   
-   SourceLocation IdLoc; 
-   
-   /// When the receiver in property access is 'super', this is 
-   /// the location of the 'super' keyword.  When it's an interface, 
-   /// this is that interface. 
-   SourceLocation ReceiverLoc; 
-   llvm::PointerUnion<Stmt *, const Type *, ObjCInterfaceDecl *> Receiver; 
-   
- public: 
-   ObjCPropertyRefExpr(ObjCPropertyDecl *PD, QualType t, ExprValueKind VK, 
-                       ExprObjectKind OK, SourceLocation l, Expr *base) 
-       : Expr(ObjCPropertyRefExprClass, t, VK, OK), PropertyOrGetter(PD, false), 
-         IdLoc(l), Receiver(base) { 
-     assert(t->isSpecificPlaceholderType(BuiltinType::PseudoObject)); 
-     setDependence(computeDependence(this)); 
-   } 
-   
-   ObjCPropertyRefExpr(ObjCPropertyDecl *PD, QualType t, ExprValueKind VK, 
-                       ExprObjectKind OK, SourceLocation l, SourceLocation sl, 
-                       QualType st) 
-       : Expr(ObjCPropertyRefExprClass, t, VK, OK), PropertyOrGetter(PD, false), 
-         IdLoc(l), ReceiverLoc(sl), Receiver(st.getTypePtr()) { 
-     assert(t->isSpecificPlaceholderType(BuiltinType::PseudoObject)); 
-     setDependence(computeDependence(this)); 
-   } 
-   
-   ObjCPropertyRefExpr(ObjCMethodDecl *Getter, ObjCMethodDecl *Setter, 
-                       QualType T, ExprValueKind VK, ExprObjectKind OK, 
-                       SourceLocation IdLoc, Expr *Base) 
-       : Expr(ObjCPropertyRefExprClass, T, VK, OK), 
-         PropertyOrGetter(Getter, true), SetterAndMethodRefFlags(Setter, 0), 
-         IdLoc(IdLoc), Receiver(Base) { 
-     assert(T->isSpecificPlaceholderType(BuiltinType::PseudoObject)); 
-     setDependence(computeDependence(this)); 
-   } 
-   
-   ObjCPropertyRefExpr(ObjCMethodDecl *Getter, ObjCMethodDecl *Setter, 
-                       QualType T, ExprValueKind VK, ExprObjectKind OK, 
-                       SourceLocation IdLoc, SourceLocation SuperLoc, 
-                       QualType SuperTy) 
-       : Expr(ObjCPropertyRefExprClass, T, VK, OK), 
-         PropertyOrGetter(Getter, true), SetterAndMethodRefFlags(Setter, 0), 
-         IdLoc(IdLoc), ReceiverLoc(SuperLoc), Receiver(SuperTy.getTypePtr()) { 
-     assert(T->isSpecificPlaceholderType(BuiltinType::PseudoObject)); 
-     setDependence(computeDependence(this)); 
-   } 
-   
-   ObjCPropertyRefExpr(ObjCMethodDecl *Getter, ObjCMethodDecl *Setter, 
-                       QualType T, ExprValueKind VK, ExprObjectKind OK, 
-                       SourceLocation IdLoc, SourceLocation ReceiverLoc, 
-                       ObjCInterfaceDecl *Receiver) 
-       : Expr(ObjCPropertyRefExprClass, T, VK, OK), 
-         PropertyOrGetter(Getter, true), SetterAndMethodRefFlags(Setter, 0), 
-         IdLoc(IdLoc), ReceiverLoc(ReceiverLoc), Receiver(Receiver) { 
-     assert(T->isSpecificPlaceholderType(BuiltinType::PseudoObject)); 
-     setDependence(computeDependence(this)); 
-   } 
-   
-   explicit ObjCPropertyRefExpr(EmptyShell Empty) 
-       : Expr(ObjCPropertyRefExprClass, Empty) {} 
-   
-   bool isImplicitProperty() const { return PropertyOrGetter.getInt(); } 
-   bool isExplicitProperty() const { return !PropertyOrGetter.getInt(); } 
-   
-   ObjCPropertyDecl *getExplicitProperty() const { 
-     assert(!isImplicitProperty()); 
-     return cast<ObjCPropertyDecl>(PropertyOrGetter.getPointer()); 
-   } 
-   
-   ObjCMethodDecl *getImplicitPropertyGetter() const { 
-     assert(isImplicitProperty()); 
-     return cast_or_null<ObjCMethodDecl>(PropertyOrGetter.getPointer()); 
-   } 
-   
-   ObjCMethodDecl *getImplicitPropertySetter() const { 
-     assert(isImplicitProperty()); 
-     return SetterAndMethodRefFlags.getPointer(); 
-   } 
-   
-   Selector getGetterSelector() const { 
-     if (isImplicitProperty()) 
-       return getImplicitPropertyGetter()->getSelector(); 
-     return getExplicitProperty()->getGetterName(); 
-   } 
-   
-   Selector getSetterSelector() const { 
-     if (isImplicitProperty()) 
-       return getImplicitPropertySetter()->getSelector(); 
-     return getExplicitProperty()->getSetterName(); 
-   } 
-   
-   /// True if the property reference will result in a message to the 
-   /// getter. 
-   /// This applies to both implicit and explicit property references. 
-   bool isMessagingGetter() const { 
-     return SetterAndMethodRefFlags.getInt() & MethodRef_Getter; 
-   } 
-   
-   /// True if the property reference will result in a message to the 
-   /// setter. 
-   /// This applies to both implicit and explicit property references. 
-   bool isMessagingSetter() const { 
-     return SetterAndMethodRefFlags.getInt() & MethodRef_Setter; 
-   } 
-   
-   void setIsMessagingGetter(bool val = true) { 
-     setMethodRefFlag(MethodRef_Getter, val); 
-   } 
-   
-   void setIsMessagingSetter(bool val = true) { 
-     setMethodRefFlag(MethodRef_Setter, val); 
-   } 
-   
-   const Expr *getBase() const { 
-     return cast<Expr>(Receiver.get<Stmt*>()); 
-   } 
-   Expr *getBase() { 
-     return cast<Expr>(Receiver.get<Stmt*>()); 
-   } 
-   
-   SourceLocation getLocation() const { return IdLoc; } 
-   
-   SourceLocation getReceiverLocation() const { return ReceiverLoc; } 
-   
-   QualType getSuperReceiverType() const { 
-     return QualType(Receiver.get<const Type*>(), 0); 
-   } 
-   
-   ObjCInterfaceDecl *getClassReceiver() const { 
-     return Receiver.get<ObjCInterfaceDecl*>(); 
-   } 
-   
-   bool isObjectReceiver() const { return Receiver.is<Stmt*>(); } 
-   bool isSuperReceiver() const { return Receiver.is<const Type*>(); } 
-   bool isClassReceiver() const { return Receiver.is<ObjCInterfaceDecl*>(); } 
-   
-   /// Determine the type of the base, regardless of the kind of receiver. 
-   QualType getReceiverType(const ASTContext &ctx) const; 
-   
-   SourceLocation getBeginLoc() const LLVM_READONLY { 
-     return isObjectReceiver() ? getBase()->getBeginLoc() 
-                               : getReceiverLocation(); 
-   } 
-   
-   SourceLocation getEndLoc() const LLVM_READONLY { return IdLoc; } 
-   
-   // Iterators 
-   child_range children() { 
-     if (Receiver.is<Stmt*>()) { 
-       Stmt **begin = reinterpret_cast<Stmt**>(&Receiver); // hack! 
-       return child_range(begin, begin+1); 
-     } 
-     return child_range(child_iterator(), child_iterator()); 
-   } 
-   
-   const_child_range children() const { 
-     auto Children = const_cast<ObjCPropertyRefExpr *>(this)->children(); 
-     return const_child_range(Children.begin(), Children.end()); 
-   } 
-   
-   static bool classof(const Stmt *T) { 
-     return T->getStmtClass() == ObjCPropertyRefExprClass; 
-   } 
-   
- private: 
-   friend class ASTStmtReader; 
-   friend class ASTStmtWriter; 
-   
-   void setExplicitProperty(ObjCPropertyDecl *D, unsigned methRefFlags) { 
-     PropertyOrGetter.setPointer(D); 
-     PropertyOrGetter.setInt(false); 
-     SetterAndMethodRefFlags.setPointer(nullptr); 
-     SetterAndMethodRefFlags.setInt(methRefFlags); 
-   } 
-   
-   void setImplicitProperty(ObjCMethodDecl *Getter, ObjCMethodDecl *Setter, 
-                            unsigned methRefFlags) { 
-     PropertyOrGetter.setPointer(Getter); 
-     PropertyOrGetter.setInt(true); 
-     SetterAndMethodRefFlags.setPointer(Setter); 
-     SetterAndMethodRefFlags.setInt(methRefFlags); 
-   } 
-   
-   void setBase(Expr *Base) { Receiver = Base; } 
-   void setSuperReceiver(QualType T) { Receiver = T.getTypePtr(); } 
-   void setClassReceiver(ObjCInterfaceDecl *D) { Receiver = D; } 
-   
-   void setLocation(SourceLocation L) { IdLoc = L; } 
-   void setReceiverLocation(SourceLocation Loc) { ReceiverLoc = Loc; } 
-   
-   void setMethodRefFlag(MethodRefFlags flag, bool val) { 
-     unsigned f = SetterAndMethodRefFlags.getInt(); 
-     if (val) 
-       f |= flag; 
-     else 
-       f &= ~flag; 
-     SetterAndMethodRefFlags.setInt(f); 
-   } 
- }; 
-   
- /// ObjCSubscriptRefExpr - used for array and dictionary subscripting. 
- /// array[4] = array[3]; dictionary[key] = dictionary[alt_key]; 
- class ObjCSubscriptRefExpr : public Expr { 
-   // Location of ']' in an indexing expression. 
-   SourceLocation RBracket; 
-   
-   // array/dictionary base expression. 
-   // for arrays, this is a numeric expression. For dictionaries, this is 
-   // an objective-c object pointer expression. 
-   enum { BASE, KEY, END_EXPR }; 
-   Stmt* SubExprs[END_EXPR]; 
-   
-   ObjCMethodDecl *GetAtIndexMethodDecl; 
-   
-   // For immutable objects this is null. When ObjCSubscriptRefExpr is to read 
-   // an indexed object this is null too. 
-   ObjCMethodDecl *SetAtIndexMethodDecl; 
-   
- public: 
-   ObjCSubscriptRefExpr(Expr *base, Expr *key, QualType T, ExprValueKind VK, 
-                        ExprObjectKind OK, ObjCMethodDecl *getMethod, 
-                        ObjCMethodDecl *setMethod, SourceLocation RB) 
-       : Expr(ObjCSubscriptRefExprClass, T, VK, OK), RBracket(RB), 
-         GetAtIndexMethodDecl(getMethod), SetAtIndexMethodDecl(setMethod) { 
-     SubExprs[BASE] = base; 
-     SubExprs[KEY] = key; 
-     setDependence(computeDependence(this)); 
-   } 
-   
-   explicit ObjCSubscriptRefExpr(EmptyShell Empty) 
-       : Expr(ObjCSubscriptRefExprClass, Empty) {} 
-   
-   SourceLocation getRBracket() const { return RBracket; } 
-   void setRBracket(SourceLocation RB) { RBracket = RB; } 
-   
-   SourceLocation getBeginLoc() const LLVM_READONLY { 
-     return SubExprs[BASE]->getBeginLoc(); 
-   } 
-   
-   SourceLocation getEndLoc() const LLVM_READONLY { return RBracket; } 
-   
-   Expr *getBaseExpr() const { return cast<Expr>(SubExprs[BASE]); } 
-   void setBaseExpr(Stmt *S) { SubExprs[BASE] = S; } 
-   
-   Expr *getKeyExpr() const { return cast<Expr>(SubExprs[KEY]); } 
-   void setKeyExpr(Stmt *S) { SubExprs[KEY] = S; } 
-   
-   ObjCMethodDecl *getAtIndexMethodDecl() const { 
-     return GetAtIndexMethodDecl; 
-   } 
-   
-   ObjCMethodDecl *setAtIndexMethodDecl() const { 
-     return SetAtIndexMethodDecl; 
-   } 
-   
-   bool isArraySubscriptRefExpr() const { 
-     return getKeyExpr()->getType()->isIntegralOrEnumerationType(); 
-   } 
-   
-   child_range children() { 
-     return child_range(SubExprs, SubExprs+END_EXPR); 
-   } 
-   
-   const_child_range children() const { 
-     return const_child_range(SubExprs, SubExprs + END_EXPR); 
-   } 
-   
-   static bool classof(const Stmt *T) { 
-     return T->getStmtClass() == ObjCSubscriptRefExprClass; 
-   } 
-   
- private: 
-   friend class ASTStmtReader; 
- }; 
-   
- /// An expression that sends a message to the given Objective-C 
- /// object or class. 
- /// 
- /// The following contains two message send expressions: 
- /// 
- /// \code 
- ///   [[NSString alloc] initWithString:@"Hello"] 
- /// \endcode 
- /// 
- /// The innermost message send invokes the "alloc" class method on the 
- /// NSString class, while the outermost message send invokes the 
- /// "initWithString" instance method on the object returned from 
- /// NSString's "alloc". In all, an Objective-C message send can take 
- /// on four different (although related) forms: 
- /// 
- ///   1. Send to an object instance. 
- ///   2. Send to a class. 
- ///   3. Send to the superclass instance of the current class. 
- ///   4. Send to the superclass of the current class. 
- /// 
- /// All four kinds of message sends are modeled by the ObjCMessageExpr 
- /// class, and can be distinguished via \c getReceiverKind(). Example: 
- /// 
- /// The "void *" trailing objects are actually ONE void * (the 
- /// receiver pointer), and NumArgs Expr *. But due to the 
- /// implementation of children(), these must be together contiguously. 
- class ObjCMessageExpr final 
-     : public Expr, 
-       private llvm::TrailingObjects<ObjCMessageExpr, void *, SourceLocation> { 
-   /// Stores either the selector that this message is sending 
-   /// to (when \c HasMethod is zero) or an \c ObjCMethodDecl pointer 
-   /// referring to the method that we type-checked against. 
-   uintptr_t SelectorOrMethod = 0; 
-   
-   enum { NumArgsBitWidth = 16 }; 
-   
-   /// The number of arguments in the message send, not 
-   /// including the receiver. 
-   unsigned NumArgs : NumArgsBitWidth; 
-   
-   /// The kind of message send this is, which is one of the 
-   /// ReceiverKind values. 
-   /// 
-   /// We pad this out to a byte to avoid excessive masking and shifting. 
-   unsigned Kind : 8; 
-   
-   /// Whether we have an actual method prototype in \c 
-   /// SelectorOrMethod. 
-   /// 
-   /// When non-zero, we have a method declaration; otherwise, we just 
-   /// have a selector. 
-   unsigned HasMethod : 1; 
-   
-   /// Whether this message send is a "delegate init call", 
-   /// i.e. a call of an init method on self from within an init method. 
-   unsigned IsDelegateInitCall : 1; 
-   
-   /// Whether this message send was implicitly generated by 
-   /// the implementation rather than explicitly written by the user. 
-   unsigned IsImplicit : 1; 
-   
-   /// Whether the locations of the selector identifiers are in a 
-   /// "standard" position, a enum SelectorLocationsKind. 
-   unsigned SelLocsKind : 2; 
-   
-   /// When the message expression is a send to 'super', this is 
-   /// the location of the 'super' keyword. 
-   SourceLocation SuperLoc; 
-   
-   /// The source locations of the open and close square 
-   /// brackets ('[' and ']', respectively). 
-   SourceLocation LBracLoc, RBracLoc; 
-   
-   ObjCMessageExpr(EmptyShell Empty, unsigned NumArgs) 
-       : Expr(ObjCMessageExprClass, Empty), Kind(0), HasMethod(false), 
-         IsDelegateInitCall(false), IsImplicit(false), SelLocsKind(0) { 
-     setNumArgs(NumArgs); 
-   } 
-   
-   ObjCMessageExpr(QualType T, ExprValueKind VK, 
-                   SourceLocation LBracLoc, 
-                   SourceLocation SuperLoc, 
-                   bool IsInstanceSuper, 
-                   QualType SuperType, 
-                   Selector Sel, 
-                   ArrayRef<SourceLocation> SelLocs, 
-                   SelectorLocationsKind SelLocsK, 
-                   ObjCMethodDecl *Method, 
-                   ArrayRef<Expr *> Args, 
-                   SourceLocation RBracLoc, 
-                   bool isImplicit); 
-   ObjCMessageExpr(QualType T, ExprValueKind VK, 
-                   SourceLocation LBracLoc, 
-                   TypeSourceInfo *Receiver, 
-                   Selector Sel, 
-                   ArrayRef<SourceLocation> SelLocs, 
-                   SelectorLocationsKind SelLocsK, 
-                   ObjCMethodDecl *Method, 
-                   ArrayRef<Expr *> Args, 
-                   SourceLocation RBracLoc, 
-                   bool isImplicit); 
-   ObjCMessageExpr(QualType T, ExprValueKind VK, 
-                   SourceLocation LBracLoc, 
-                   Expr *Receiver, 
-                   Selector Sel, 
-                   ArrayRef<SourceLocation> SelLocs, 
-                   SelectorLocationsKind SelLocsK, 
-                   ObjCMethodDecl *Method, 
-                   ArrayRef<Expr *> Args, 
-                   SourceLocation RBracLoc, 
-                   bool isImplicit); 
-   
-   size_t numTrailingObjects(OverloadToken<void *>) const { return NumArgs + 1; } 
-   
-   void setNumArgs(unsigned Num) { 
-     assert((Num >> NumArgsBitWidth) == 0 && "Num of args is out of range!"); 
-     NumArgs = Num; 
-   } 
-   
-   void initArgsAndSelLocs(ArrayRef<Expr *> Args, 
-                           ArrayRef<SourceLocation> SelLocs, 
-                           SelectorLocationsKind SelLocsK); 
-   
-   /// Retrieve the pointer value of the message receiver. 
-   void *getReceiverPointer() const { return *getTrailingObjects<void *>(); } 
-   
-   /// Set the pointer value of the message receiver. 
-   void setReceiverPointer(void *Value) { 
-     *getTrailingObjects<void *>() = Value; 
-   } 
-   
-   SelectorLocationsKind getSelLocsKind() const { 
-     return (SelectorLocationsKind)SelLocsKind; 
-   } 
-   
-   bool hasStandardSelLocs() const { 
-     return getSelLocsKind() != SelLoc_NonStandard; 
-   } 
-   
-   /// Get a pointer to the stored selector identifiers locations array. 
-   /// No locations will be stored if HasStandardSelLocs is true. 
-   SourceLocation *getStoredSelLocs() { 
-     return getTrailingObjects<SourceLocation>(); 
-   } 
-   const SourceLocation *getStoredSelLocs() const { 
-     return getTrailingObjects<SourceLocation>(); 
-   } 
-   
-   /// Get the number of stored selector identifiers locations. 
-   /// No locations will be stored if HasStandardSelLocs is true. 
-   unsigned getNumStoredSelLocs() const { 
-     if (hasStandardSelLocs()) 
-       return 0; 
-     return getNumSelectorLocs(); 
-   } 
-   
-   static ObjCMessageExpr *alloc(const ASTContext &C, 
-                                 ArrayRef<Expr *> Args, 
-                                 SourceLocation RBraceLoc, 
-                                 ArrayRef<SourceLocation> SelLocs, 
-                                 Selector Sel, 
-                                 SelectorLocationsKind &SelLocsK); 
-   static ObjCMessageExpr *alloc(const ASTContext &C, 
-                                 unsigned NumArgs, 
-                                 unsigned NumStoredSelLocs); 
-   
- public: 
-   friend class ASTStmtReader; 
-   friend class ASTStmtWriter; 
-   friend TrailingObjects; 
-   
-   /// The kind of receiver this message is sending to. 
-   enum ReceiverKind { 
-     /// The receiver is a class. 
-     Class = 0, 
-   
-     /// The receiver is an object instance. 
-     Instance, 
-   
-     /// The receiver is a superclass. 
-     SuperClass, 
-   
-     /// The receiver is the instance of the superclass object. 
-     SuperInstance 
-   }; 
-   
-   /// Create a message send to super. 
-   /// 
-   /// \param Context The ASTContext in which this expression will be created. 
-   /// 
-   /// \param T The result type of this message. 
-   /// 
-   /// \param VK The value kind of this message.  A message returning 
-   /// a l-value or r-value reference will be an l-value or x-value, 
-   /// respectively. 
-   /// 
-   /// \param LBracLoc The location of the open square bracket '['. 
-   /// 
-   /// \param SuperLoc The location of the "super" keyword. 
-   /// 
-   /// \param IsInstanceSuper Whether this is an instance "super" 
-   /// message (otherwise, it's a class "super" message). 
-   /// 
-   /// \param Sel The selector used to determine which method gets called. 
-   /// 
-   /// \param Method The Objective-C method against which this message 
-   /// send was type-checked. May be nullptr. 
-   /// 
-   /// \param Args The message send arguments. 
-   /// 
-   /// \param RBracLoc The location of the closing square bracket ']'. 
-   static ObjCMessageExpr *Create(const ASTContext &Context, QualType T, 
-                                  ExprValueKind VK, 
-                                  SourceLocation LBracLoc, 
-                                  SourceLocation SuperLoc, 
-                                  bool IsInstanceSuper, 
-                                  QualType SuperType, 
-                                  Selector Sel, 
-                                  ArrayRef<SourceLocation> SelLocs, 
-                                  ObjCMethodDecl *Method, 
-                                  ArrayRef<Expr *> Args, 
-                                  SourceLocation RBracLoc, 
-                                  bool isImplicit); 
-   
-   /// Create a class message send. 
-   /// 
-   /// \param Context The ASTContext in which this expression will be created. 
-   /// 
-   /// \param T The result type of this message. 
-   /// 
-   /// \param VK The value kind of this message.  A message returning 
-   /// a l-value or r-value reference will be an l-value or x-value, 
-   /// respectively. 
-   /// 
-   /// \param LBracLoc The location of the open square bracket '['. 
-   /// 
-   /// \param Receiver The type of the receiver, including 
-   /// source-location information. 
-   /// 
-   /// \param Sel The selector used to determine which method gets called. 
-   /// 
-   /// \param Method The Objective-C method against which this message 
-   /// send was type-checked. May be nullptr. 
-   /// 
-   /// \param Args The message send arguments. 
-   /// 
-   /// \param RBracLoc The location of the closing square bracket ']'. 
-   static ObjCMessageExpr *Create(const ASTContext &Context, QualType T, 
-                                  ExprValueKind VK, 
-                                  SourceLocation LBracLoc, 
-                                  TypeSourceInfo *Receiver, 
-                                  Selector Sel, 
-                                  ArrayRef<SourceLocation> SelLocs, 
-                                  ObjCMethodDecl *Method, 
-                                  ArrayRef<Expr *> Args, 
-                                  SourceLocation RBracLoc, 
-                                  bool isImplicit); 
-   
-   /// Create an instance message send. 
-   /// 
-   /// \param Context The ASTContext in which this expression will be created. 
-   /// 
-   /// \param T The result type of this message. 
-   /// 
-   /// \param VK The value kind of this message.  A message returning 
-   /// a l-value or r-value reference will be an l-value or x-value, 
-   /// respectively. 
-   /// 
-   /// \param LBracLoc The location of the open square bracket '['. 
-   /// 
-   /// \param Receiver The expression used to produce the object that 
-   /// will receive this message. 
-   /// 
-   /// \param Sel The selector used to determine which method gets called. 
-   /// 
-   /// \param Method The Objective-C method against which this message 
-   /// send was type-checked. May be nullptr. 
-   /// 
-   /// \param Args The message send arguments. 
-   /// 
-   /// \param RBracLoc The location of the closing square bracket ']'. 
-   static ObjCMessageExpr *Create(const ASTContext &Context, QualType T, 
-                                  ExprValueKind VK, 
-                                  SourceLocation LBracLoc, 
-                                  Expr *Receiver, 
-                                  Selector Sel, 
-                                  ArrayRef<SourceLocation> SeLocs, 
-                                  ObjCMethodDecl *Method, 
-                                  ArrayRef<Expr *> Args, 
-                                  SourceLocation RBracLoc, 
-                                  bool isImplicit); 
-   
-   /// Create an empty Objective-C message expression, to be 
-   /// filled in by subsequent calls. 
-   /// 
-   /// \param Context The context in which the message send will be created. 
-   /// 
-   /// \param NumArgs The number of message arguments, not including 
-   /// the receiver. 
-   static ObjCMessageExpr *CreateEmpty(const ASTContext &Context, 
-                                       unsigned NumArgs, 
-                                       unsigned NumStoredSelLocs); 
-   
-   /// Indicates whether the message send was implicitly 
-   /// generated by the implementation. If false, it was written explicitly 
-   /// in the source code. 
-   bool isImplicit() const { return IsImplicit; } 
-   
-   /// Determine the kind of receiver that this message is being 
-   /// sent to. 
-   ReceiverKind getReceiverKind() const { return (ReceiverKind)Kind; } 
-   
-   /// \return the return type of the message being sent. 
-   /// This is not always the type of the message expression itself because 
-   /// of references (the expression would not have a reference type). 
-   /// It is also not always the declared return type of the method because 
-   /// of `instancetype` (in that case it's an expression type). 
-   QualType getCallReturnType(ASTContext &Ctx) const; 
-   
-   /// Source range of the receiver. 
-   SourceRange getReceiverRange() const; 
-   
-   /// Determine whether this is an instance message to either a 
-   /// computed object or to super. 
-   bool isInstanceMessage() const { 
-     return getReceiverKind() == Instance || getReceiverKind() == SuperInstance; 
-   } 
-   
-   /// Determine whether this is an class message to either a 
-   /// specified class or to super. 
-   bool isClassMessage() const { 
-     return getReceiverKind() == Class || getReceiverKind() == SuperClass; 
-   } 
-   
-   /// Returns the object expression (receiver) for an instance message, 
-   /// or null for a message that is not an instance message. 
-   Expr *getInstanceReceiver() { 
-     if (getReceiverKind() == Instance) 
-       return static_cast<Expr *>(getReceiverPointer()); 
-   
-     return nullptr; 
-   } 
-   const Expr *getInstanceReceiver() const { 
-     return const_cast<ObjCMessageExpr*>(this)->getInstanceReceiver(); 
-   } 
-   
-   /// Turn this message send into an instance message that 
-   /// computes the receiver object with the given expression. 
-   void setInstanceReceiver(Expr *rec) { 
-     Kind = Instance; 
-     setReceiverPointer(rec); 
-   } 
-   
-   /// Returns the type of a class message send, or NULL if the 
-   /// message is not a class message. 
-   QualType getClassReceiver() const { 
-     if (TypeSourceInfo *TSInfo = getClassReceiverTypeInfo()) 
-       return TSInfo->getType(); 
-   
-     return {}; 
-   } 
-   
-   /// Returns a type-source information of a class message 
-   /// send, or nullptr if the message is not a class message. 
-   TypeSourceInfo *getClassReceiverTypeInfo() const { 
-     if (getReceiverKind() == Class) 
-       return reinterpret_cast<TypeSourceInfo *>(getReceiverPointer()); 
-     return nullptr; 
-   } 
-   
-   void setClassReceiver(TypeSourceInfo *TSInfo) { 
-     Kind = Class; 
-     setReceiverPointer(TSInfo); 
-   } 
-   
-   /// Retrieve the location of the 'super' keyword for a class 
-   /// or instance message to 'super', otherwise an invalid source location. 
-   SourceLocation getSuperLoc() const { 
-     if (getReceiverKind() == SuperInstance || getReceiverKind() == SuperClass) 
-       return SuperLoc; 
-   
-     return SourceLocation(); 
-   } 
-   
-   /// Retrieve the receiver type to which this message is being directed. 
-   /// 
-   /// This routine cross-cuts all of the different kinds of message 
-   /// sends to determine what the underlying (statically known) type 
-   /// of the receiver will be; use \c getReceiverKind() to determine 
-   /// whether the message is a class or an instance method, whether it 
-   /// is a send to super or not, etc. 
-   /// 
-   /// \returns The type of the receiver. 
-   QualType getReceiverType() const; 
-   
-   /// Retrieve the Objective-C interface to which this message 
-   /// is being directed, if known. 
-   /// 
-   /// This routine cross-cuts all of the different kinds of message 
-   /// sends to determine what the underlying (statically known) type 
-   /// of the receiver will be; use \c getReceiverKind() to determine 
-   /// whether the message is a class or an instance method, whether it 
-   /// is a send to super or not, etc. 
-   /// 
-   /// \returns The Objective-C interface if known, otherwise nullptr. 
-   ObjCInterfaceDecl *getReceiverInterface() const; 
-   
-   /// Retrieve the type referred to by 'super'. 
-   /// 
-   /// The returned type will either be an ObjCInterfaceType (for an 
-   /// class message to super) or an ObjCObjectPointerType that refers 
-   /// to a class (for an instance message to super); 
-   QualType getSuperType() const { 
-     if (getReceiverKind() == SuperInstance || getReceiverKind() == SuperClass) 
-       return QualType::getFromOpaquePtr(getReceiverPointer()); 
-   
-     return QualType(); 
-   } 
-   
-   void setSuper(SourceLocation Loc, QualType T, bool IsInstanceSuper) { 
-     Kind = IsInstanceSuper? SuperInstance : SuperClass; 
-     SuperLoc = Loc; 
-     setReceiverPointer(T.getAsOpaquePtr()); 
-   } 
-   
-   Selector getSelector() const; 
-   
-   void setSelector(Selector S) { 
-     HasMethod = false; 
-     SelectorOrMethod = reinterpret_cast<uintptr_t>(S.getAsOpaquePtr()); 
-   } 
-   
-   const ObjCMethodDecl *getMethodDecl() const { 
-     if (HasMethod) 
-       return reinterpret_cast<const ObjCMethodDecl *>(SelectorOrMethod); 
-   
-     return nullptr; 
-   } 
-   
-   ObjCMethodDecl *getMethodDecl() { 
-     if (HasMethod) 
-       return reinterpret_cast<ObjCMethodDecl *>(SelectorOrMethod); 
-   
-     return nullptr; 
-   } 
-   
-   void setMethodDecl(ObjCMethodDecl *MD) { 
-     HasMethod = true; 
-     SelectorOrMethod = reinterpret_cast<uintptr_t>(MD); 
-   } 
-   
-   ObjCMethodFamily getMethodFamily() const { 
-     if (HasMethod) return getMethodDecl()->getMethodFamily(); 
-     return getSelector().getMethodFamily(); 
-   } 
-   
-   /// Return the number of actual arguments in this message, 
-   /// not counting the receiver. 
-   unsigned getNumArgs() const { return NumArgs; } 
-   
-   /// Retrieve the arguments to this message, not including the 
-   /// receiver. 
-   Expr **getArgs() { 
-     return reinterpret_cast<Expr **>(getTrailingObjects<void *>() + 1); 
-   } 
-   const Expr * const *getArgs() const { 
-     return reinterpret_cast<const Expr *const *>(getTrailingObjects<void *>() + 
-                                                  1); 
-   } 
-   
-   /// getArg - Return the specified argument. 
-   Expr *getArg(unsigned Arg) { 
-     assert(Arg < NumArgs && "Arg access out of range!"); 
-     return getArgs()[Arg]; 
-   } 
-   const Expr *getArg(unsigned Arg) const { 
-     assert(Arg < NumArgs && "Arg access out of range!"); 
-     return getArgs()[Arg]; 
-   } 
-   
-   /// setArg - Set the specified argument. 
-   void setArg(unsigned Arg, Expr *ArgExpr) { 
-     assert(Arg < NumArgs && "Arg access out of range!"); 
-     getArgs()[Arg] = ArgExpr; 
-   } 
-   
-   /// isDelegateInitCall - Answers whether this message send has been 
-   /// tagged as a "delegate init call", i.e. a call to a method in the 
-   /// -init family on self from within an -init method implementation. 
-   bool isDelegateInitCall() const { return IsDelegateInitCall; } 
-   void setDelegateInitCall(bool isDelegate) { IsDelegateInitCall = isDelegate; } 
-   
-   SourceLocation getLeftLoc() const { return LBracLoc; } 
-   SourceLocation getRightLoc() const { return RBracLoc; } 
-   
-   SourceLocation getSelectorStartLoc() const { 
-     if (isImplicit()) 
-       return getBeginLoc(); 
-     return getSelectorLoc(0); 
-   } 
-   
-   SourceLocation getSelectorLoc(unsigned Index) const { 
-     assert(Index < getNumSelectorLocs() && "Index out of range!"); 
-     if (hasStandardSelLocs()) 
-       return getStandardSelectorLoc( 
-           Index, getSelector(), getSelLocsKind() == SelLoc_StandardWithSpace, 
-           llvm::ArrayRef(const_cast<Expr **>(getArgs()), getNumArgs()), 
-           RBracLoc); 
-     return getStoredSelLocs()[Index]; 
-   } 
-   
-   void getSelectorLocs(SmallVectorImpl<SourceLocation> &SelLocs) const; 
-   
-   unsigned getNumSelectorLocs() const { 
-     if (isImplicit()) 
-       return 0; 
-     Selector Sel = getSelector(); 
-     if (Sel.isUnarySelector()) 
-       return 1; 
-     return Sel.getNumArgs(); 
-   } 
-   
-   void setSourceRange(SourceRange R) { 
-     LBracLoc = R.getBegin(); 
-     RBracLoc = R.getEnd(); 
-   } 
-   
-   SourceLocation getBeginLoc() const LLVM_READONLY { return LBracLoc; } 
-   SourceLocation getEndLoc() const LLVM_READONLY { return RBracLoc; } 
-   
-   // Iterators 
-   child_range children(); 
-   
-   const_child_range children() const; 
-   
-   using arg_iterator = ExprIterator; 
-   using const_arg_iterator = ConstExprIterator; 
-   
-   llvm::iterator_range<arg_iterator> arguments() { 
-     return llvm::make_range(arg_begin(), arg_end()); 
-   } 
-   
-   llvm::iterator_range<const_arg_iterator> arguments() const { 
-     return llvm::make_range(arg_begin(), arg_end()); 
-   } 
-   
-   arg_iterator arg_begin() { return reinterpret_cast<Stmt **>(getArgs()); } 
-   
-   arg_iterator arg_end()   { 
-     return reinterpret_cast<Stmt **>(getArgs() + NumArgs); 
-   } 
-   
-   const_arg_iterator arg_begin() const { 
-     return reinterpret_cast<Stmt const * const*>(getArgs()); 
-   } 
-   
-   const_arg_iterator arg_end() const { 
-     return reinterpret_cast<Stmt const * const*>(getArgs() + NumArgs); 
-   } 
-   
-   static bool classof(const Stmt *T) { 
-     return T->getStmtClass() == ObjCMessageExprClass; 
-   } 
- }; 
-   
- /// ObjCIsaExpr - Represent X->isa and X.isa when X is an ObjC 'id' type. 
- /// (similar in spirit to MemberExpr). 
- class ObjCIsaExpr : public Expr { 
-   /// Base - the expression for the base object pointer. 
-   Stmt *Base; 
-   
-   /// IsaMemberLoc - This is the location of the 'isa'. 
-   SourceLocation IsaMemberLoc; 
-   
-   /// OpLoc - This is the location of '.' or '->' 
-   SourceLocation OpLoc; 
-   
-   /// IsArrow - True if this is "X->F", false if this is "X.F". 
-   bool IsArrow; 
-   
- public: 
-   ObjCIsaExpr(Expr *base, bool isarrow, SourceLocation l, SourceLocation oploc, 
-               QualType ty) 
-       : Expr(ObjCIsaExprClass, ty, VK_LValue, OK_Ordinary), Base(base), 
-         IsaMemberLoc(l), OpLoc(oploc), IsArrow(isarrow) { 
-     setDependence(computeDependence(this)); 
-   } 
-   
-   /// Build an empty expression. 
-   explicit ObjCIsaExpr(EmptyShell Empty) : Expr(ObjCIsaExprClass, Empty) {} 
-   
-   void setBase(Expr *E) { Base = E; } 
-   Expr *getBase() const { return cast<Expr>(Base); } 
-   
-   bool isArrow() const { return IsArrow; } 
-   void setArrow(bool A) { IsArrow = A; } 
-   
-   /// getMemberLoc - Return the location of the "member", in X->F, it is the 
-   /// location of 'F'. 
-   SourceLocation getIsaMemberLoc() const { return IsaMemberLoc; } 
-   void setIsaMemberLoc(SourceLocation L) { IsaMemberLoc = L; } 
-   
-   SourceLocation getOpLoc() const { return OpLoc; } 
-   void setOpLoc(SourceLocation L) { OpLoc = L; } 
-   
-   SourceLocation getBeginLoc() const LLVM_READONLY { 
-     return getBase()->getBeginLoc(); 
-   } 
-   
-   SourceLocation getBaseLocEnd() const LLVM_READONLY { 
-     return getBase()->getEndLoc(); 
-   } 
-   
-   SourceLocation getEndLoc() const LLVM_READONLY { return IsaMemberLoc; } 
-   
-   SourceLocation getExprLoc() const LLVM_READONLY { return IsaMemberLoc; } 
-   
-   // Iterators 
-   child_range children() { return child_range(&Base, &Base+1); } 
-   
-   const_child_range children() const { 
-     return const_child_range(&Base, &Base + 1); 
-   } 
-   
-   static bool classof(const Stmt *T) { 
-     return T->getStmtClass() == ObjCIsaExprClass; 
-   } 
- }; 
-   
- /// ObjCIndirectCopyRestoreExpr - Represents the passing of a function 
- /// argument by indirect copy-restore in ARC.  This is used to support 
- /// passing indirect arguments with the wrong lifetime, e.g. when 
- /// passing the address of a __strong local variable to an 'out' 
- /// parameter.  This expression kind is only valid in an "argument" 
- /// position to some sort of call expression. 
- /// 
- /// The parameter must have type 'pointer to T', and the argument must 
- /// have type 'pointer to U', where T and U agree except possibly in 
- /// qualification.  If the argument value is null, then a null pointer 
- /// is passed;  otherwise it points to an object A, and: 
- /// 1. A temporary object B of type T is initialized, either by 
- ///    zero-initialization (used when initializing an 'out' parameter) 
- ///    or copy-initialization (used when initializing an 'inout' 
- ///    parameter). 
- /// 2. The address of the temporary is passed to the function. 
- /// 3. If the call completes normally, A is move-assigned from B. 
- /// 4. Finally, A is destroyed immediately. 
- /// 
- /// Currently 'T' must be a retainable object lifetime and must be 
- /// __autoreleasing;  this qualifier is ignored when initializing 
- /// the value. 
- class ObjCIndirectCopyRestoreExpr : public Expr { 
-   friend class ASTReader; 
-   friend class ASTStmtReader; 
-   
-   Stmt *Operand; 
-   
-   // unsigned ObjCIndirectCopyRestoreBits.ShouldCopy : 1; 
-   
-   explicit ObjCIndirectCopyRestoreExpr(EmptyShell Empty) 
-       : Expr(ObjCIndirectCopyRestoreExprClass, Empty) {} 
-   
-   void setShouldCopy(bool shouldCopy) { 
-     ObjCIndirectCopyRestoreExprBits.ShouldCopy = shouldCopy; 
-   } 
-   
- public: 
-   ObjCIndirectCopyRestoreExpr(Expr *operand, QualType type, bool shouldCopy) 
-       : Expr(ObjCIndirectCopyRestoreExprClass, type, VK_LValue, OK_Ordinary), 
-         Operand(operand) { 
-     setShouldCopy(shouldCopy); 
-     setDependence(computeDependence(this)); 
-   } 
-   
-   Expr *getSubExpr() { return cast<Expr>(Operand); } 
-   const Expr *getSubExpr() const { return cast<Expr>(Operand); } 
-   
-   /// shouldCopy - True if we should do the 'copy' part of the 
-   /// copy-restore.  If false, the temporary will be zero-initialized. 
-   bool shouldCopy() const { return ObjCIndirectCopyRestoreExprBits.ShouldCopy; } 
-   
-   child_range children() { return child_range(&Operand, &Operand+1); } 
-   
-   const_child_range children() const { 
-     return const_child_range(&Operand, &Operand + 1); 
-   } 
-   
-   // Source locations are determined by the subexpression. 
-   SourceLocation getBeginLoc() const LLVM_READONLY { 
-     return Operand->getBeginLoc(); 
-   } 
-   SourceLocation getEndLoc() const LLVM_READONLY { 
-     return Operand->getEndLoc(); 
-   } 
-   
-   SourceLocation getExprLoc() const LLVM_READONLY { 
-     return getSubExpr()->getExprLoc(); 
-   } 
-   
-   static bool classof(const Stmt *s) { 
-     return s->getStmtClass() == ObjCIndirectCopyRestoreExprClass; 
-   } 
- }; 
-   
- /// An Objective-C "bridged" cast expression, which casts between 
- /// Objective-C pointers and C pointers, transferring ownership in the process. 
- /// 
- /// \code 
- /// NSString *str = (__bridge_transfer NSString *)CFCreateString(); 
- /// \endcode 
- class ObjCBridgedCastExpr final 
-     : public ExplicitCastExpr, 
-       private llvm::TrailingObjects<ObjCBridgedCastExpr, CXXBaseSpecifier *> { 
-   friend class ASTStmtReader; 
-   friend class ASTStmtWriter; 
-   friend class CastExpr; 
-   friend TrailingObjects; 
-   
-   SourceLocation LParenLoc; 
-   SourceLocation BridgeKeywordLoc; 
-   unsigned Kind : 2; 
-   
- public: 
-   ObjCBridgedCastExpr(SourceLocation LParenLoc, ObjCBridgeCastKind Kind, 
-                       CastKind CK, SourceLocation BridgeKeywordLoc, 
-                       TypeSourceInfo *TSInfo, Expr *Operand) 
-       : ExplicitCastExpr(ObjCBridgedCastExprClass, TSInfo->getType(), 
-                          VK_PRValue, CK, Operand, 0, false, TSInfo), 
-         LParenLoc(LParenLoc), BridgeKeywordLoc(BridgeKeywordLoc), Kind(Kind) {} 
-   
-   /// Construct an empty Objective-C bridged cast. 
-   explicit ObjCBridgedCastExpr(EmptyShell Shell) 
-       : ExplicitCastExpr(ObjCBridgedCastExprClass, Shell, 0, false) {} 
-   
-   SourceLocation getLParenLoc() const { return LParenLoc; } 
-   
-   /// Determine which kind of bridge is being performed via this cast. 
-   ObjCBridgeCastKind getBridgeKind() const { 
-     return static_cast<ObjCBridgeCastKind>(Kind); 
-   } 
-   
-   /// Retrieve the kind of bridge being performed as a string. 
-   StringRef getBridgeKindName() const; 
-   
-   /// The location of the bridge keyword. 
-   SourceLocation getBridgeKeywordLoc() const { return BridgeKeywordLoc; } 
-   
-   SourceLocation getBeginLoc() const LLVM_READONLY { return LParenLoc; } 
-   
-   SourceLocation getEndLoc() const LLVM_READONLY { 
-     return getSubExpr()->getEndLoc(); 
-   } 
-   
-   static bool classof(const Stmt *T) { 
-     return T->getStmtClass() == ObjCBridgedCastExprClass; 
-   } 
- }; 
-   
- /// A runtime availability query. 
- /// 
- /// There are 2 ways to spell this node: 
- /// \code 
- ///   @available(macos 10.10, ios 8, *); // Objective-C 
- ///   __builtin_available(macos 10.10, ios 8, *); // C, C++, and Objective-C 
- /// \endcode 
- /// 
- /// Note that we only need to keep track of one \c VersionTuple here, which is 
- /// the one that corresponds to the current deployment target. This is meant to 
- /// be used in the condition of an \c if, but it is also usable as top level 
- /// expressions. 
- /// 
- class ObjCAvailabilityCheckExpr : public Expr { 
-   friend class ASTStmtReader; 
-   
-   VersionTuple VersionToCheck; 
-   SourceLocation AtLoc, RParen; 
-   
- public: 
-   ObjCAvailabilityCheckExpr(VersionTuple VersionToCheck, SourceLocation AtLoc, 
-                             SourceLocation RParen, QualType Ty) 
-       : Expr(ObjCAvailabilityCheckExprClass, Ty, VK_PRValue, OK_Ordinary), 
-         VersionToCheck(VersionToCheck), AtLoc(AtLoc), RParen(RParen) { 
-     setDependence(ExprDependence::None); 
-   } 
-   
-   explicit ObjCAvailabilityCheckExpr(EmptyShell Shell) 
-       : Expr(ObjCAvailabilityCheckExprClass, Shell) {} 
-   
-   SourceLocation getBeginLoc() const { return AtLoc; } 
-   SourceLocation getEndLoc() const { return RParen; } 
-   SourceRange getSourceRange() const { return {AtLoc, RParen}; } 
-   
-   /// This may be '*', in which case this should fold to true. 
-   bool hasVersion() const { return !VersionToCheck.empty(); } 
-   VersionTuple getVersion() const { return VersionToCheck; } 
-   
-   child_range children() { 
-     return child_range(child_iterator(), child_iterator()); 
-   } 
-   
-   const_child_range children() const { 
-     return const_child_range(const_child_iterator(), const_child_iterator()); 
-   } 
-   
-   static bool classof(const Stmt *T) { 
-     return T->getStmtClass() == ObjCAvailabilityCheckExprClass; 
-   } 
- }; 
-   
- } // namespace clang 
-   
- #endif // LLVM_CLANG_AST_EXPROBJC_H 
-