text: //===--- Expr.h - Swift Language Expression ASTs ----------------*- C++ -*-===//
  //
  // This source file is part of the Swift.org open source project
  //
  // Copyright (c) 2014 - 2018 Apple Inc. and the Swift project authors
  // Licensed under Apache License v2.0 with Runtime Library Exception
  //
  // See https://swift.org/LICENSE.txt for license information
  // See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
  //
  //===----------------------------------------------------------------------===//
  //
  // This file defines the Expr class and subclasses.
  //
  //===----------------------------------------------------------------------===//
  
  #ifndef SWIFT_AST_EXPR_H
  #define SWIFT_AST_EXPR_H
  
  #include "swift/AST/CaptureInfo.h"
  #include "swift/AST/ConcreteDeclRef.h"
  #include "swift/AST/DeclNameLoc.h"
  #include "swift/AST/FunctionRefKind.h"
  #include "swift/AST/ProtocolConformanceRef.h"
  #include "swift/AST/TypeAlignments.h"
  #include "swift/AST/TypeLoc.h"
  #include "swift/AST/TypeRepr.h"
  #include "swift/AST/Availability.h"
  #include "swift/Basic/InlineBitfield.h"
  #include "llvm/Support/TrailingObjects.h"
  #include <utility>
  
  namespace llvm {
    struct fltSemantics;
  }
  
  namespace swift {
    enum class AccessKind : unsigned char;
    class ArchetypeType;
    class ASTContext;
    class AvailabilitySpec;
    class Type;
    class ValueDecl;
    class Decl;
    class DeclRefExpr;
    class OpenedArchetypeType;
    class Pattern;
    class SubscriptDecl;
    class Stmt;
    class BraceStmt;
    class ASTWalker;
    class Initializer;
    class VarDecl;
    class OpaqueValueExpr;
    class FuncDecl;
    class ConstructorDecl;
    class TypeDecl;
    class PatternBindingDecl;
    class ParameterList;
    class EnumElementDecl;
    class CallExpr;
  
  enum class ExprKind : uint8_t {
  #define EXPR(Id, Parent) Id,
  #define LAST_EXPR(Id) Last_Expr = Id,
  #define EXPR_RANGE(Id, FirstId, LastId) \
    First_##Id##Expr = FirstId, Last_##Id##Expr = LastId,
  #include "swift/AST/ExprNodes.def"
  };
  enum : unsigned { NumExprKindBits =
    countBitsUsed(static_cast<unsigned>(ExprKind::Last_Expr)) };
    
  /// Discriminates certain kinds of checked cast that have specialized diagnostic
  /// and/or code generation peephole behavior.
  ///
  /// This enumeration should not have any semantic effect on the behavior of a
  /// well-typed program, since the runtime can perform all casts that are
  /// statically accepted.
  enum class CheckedCastKind : unsigned {
    /// The kind has not been determined yet.
    Unresolved,
  
    /// Valid resolved kinds start here.
    First_Resolved,
  
    /// The requested cast is an implicit conversion, so this is a coercion.
    Coercion = First_Resolved,
    /// A checked cast with no known specific behavior.
    ValueCast,
    // A downcast from an array type to another array type.
    ArrayDowncast,
    // A downcast from a dictionary type to another dictionary type.
    DictionaryDowncast,
    // A downcast from a set type to another set type.
    SetDowncast,
    /// A bridging conversion that always succeeds.
    BridgingCoercion,
  
    Last_CheckedCastKind = BridgingCoercion,
  };
  
  /// What are the high-level semantics of this access?
  enum class AccessSemantics : uint8_t {
    /// On a storage reference, this is a direct access to the underlying
    /// physical storage, bypassing any observers.  The declaration must be 
    /// a variable with storage.
    ///
    /// On a function reference, this is a non-polymorphic access to a
    /// particular implementation.
    DirectToStorage,
  
    /// On a storage reference, this is a direct access to the concrete
    /// implementation of this storage, bypassing any possibility of override.
    DirectToImplementation,
  
    /// This is an ordinary access to a declaration, using whatever
    /// polymorphism is expected.
    Ordinary,
  };
  
  /// Expr - Base class for all expressions in swift.
  class alignas(8) Expr {
    Expr(const Expr&) = delete;
    void operator=(const Expr&) = delete;
  
  protected:
    union { uint64_t OpaqueBits;
  
    SWIFT_INLINE_BITFIELD_BASE(Expr, bitmax(NumExprKindBits,8)+1,
      /// The subclass of Expr that this is.
      Kind : bitmax(NumExprKindBits,8),
      /// Whether the Expr represents something directly written in source or
      /// it was implicitly generated by the type-checker.
      Implicit : 1
    );
  
    SWIFT_INLINE_BITFIELD_FULL(CollectionExpr, Expr, 64-NumExprBits,
      /// True if the type of this collection expr was inferred by the collection
      /// fallback type, like [Any].
      IsTypeDefaulted : 1,
      /// Number of comma source locations.
      NumCommas : 32 - 1 - NumExprBits,
      /// Number of entries in the collection. If this is a DictionaryExpr,
      /// each entry is a Tuple with the key and value pair.
      NumSubExprs : 32
    );
  
    SWIFT_INLINE_BITFIELD_EMPTY(LiteralExpr, Expr);
    SWIFT_INLINE_BITFIELD_EMPTY(IdentityExpr, Expr);
    SWIFT_INLINE_BITFIELD(LookupExpr, Expr, 1,
      IsSuper : 1
    );
    SWIFT_INLINE_BITFIELD_EMPTY(DynamicLookupExpr, LookupExpr);
  
    SWIFT_INLINE_BITFIELD(ParenExpr, IdentityExpr, 1,
      /// Whether we're wrapping a trailing closure expression.
      HasTrailingClosure : 1
    );
  
    SWIFT_INLINE_BITFIELD(NumberLiteralExpr, LiteralExpr, 1,
      IsNegative : 1
    );
  
    SWIFT_INLINE_BITFIELD(StringLiteralExpr, LiteralExpr, 3+1+1,
      Encoding : 3,
      IsSingleUnicodeScalar : 1,
      IsSingleExtendedGraphemeCluster : 1
    );
  
    SWIFT_INLINE_BITFIELD_FULL(InterpolatedStringLiteralExpr, LiteralExpr, 32+20,
      : NumPadBits,
      InterpolationCount : 20,
      LiteralCapacity : 32
    );
  
    SWIFT_INLINE_BITFIELD(DeclRefExpr, Expr, 2+2,
      Semantics : 2, // an AccessSemantics
      FunctionRefKind : 2
    );
  
    SWIFT_INLINE_BITFIELD(UnresolvedDeclRefExpr, Expr, 2+2,
      DeclRefKind : 2,
      FunctionRefKind : 2
    );
  
    SWIFT_INLINE_BITFIELD(MemberRefExpr, LookupExpr, 2,
      Semantics : 2 // an AccessSemantics
    );
  
    SWIFT_INLINE_BITFIELD_FULL(TupleElementExpr, Expr, 32,
      : NumPadBits,
      FieldNo : 32
    );
  
    SWIFT_INLINE_BITFIELD_FULL(TupleExpr, Expr, 1+1+1+32,
      /// Whether this tuple has a trailing closure.
      HasTrailingClosure : 1,
  
      /// Whether this tuple has any labels.
      HasElementNames : 1,
  
      /// Whether this tuple has label locations.
      HasElementNameLocations : 1,
  
      : NumPadBits,
      NumElements : 32
    );
  
    SWIFT_INLINE_BITFIELD(UnresolvedDotExpr, Expr, 2,
      FunctionRefKind : 2
    );
  
    SWIFT_INLINE_BITFIELD_FULL(SubscriptExpr, LookupExpr, 2+1+1+16,
      Semantics : 2, // an AccessSemantics
      /// Whether the SubscriptExpr also has source locations for the argument
      /// label.
      HasArgLabelLocs : 1,
      /// Whether the last argument is a trailing closure.
      HasTrailingClosure : 1,
      : NumPadBits,
      /// # of argument labels stored after the SubscriptExpr.
      NumArgLabels : 16
    );
  
    SWIFT_INLINE_BITFIELD_FULL(DynamicSubscriptExpr, DynamicLookupExpr, 1+1+16,
      /// Whether the DynamicSubscriptExpr also has source locations for the
      /// argument label.
      HasArgLabelLocs : 1,
      /// Whether the last argument is a trailing closure.
      HasTrailingClosure : 1,
      : NumPadBits,
      /// # of argument labels stored after the DynamicSubscriptExpr.
      NumArgLabels : 16
    );
  
    SWIFT_INLINE_BITFIELD_FULL(UnresolvedMemberExpr, Expr, 1+1+1+16,
      /// Whether the UnresolvedMemberExpr has arguments.
      HasArguments : 1,
      /// Whether the UnresolvedMemberExpr also has source locations for the
      /// argument label.
      HasArgLabelLocs : 1,
      /// Whether the last argument is a trailing closure.
      HasTrailingClosure : 1,
      : NumPadBits,
      /// # of argument labels stored after the UnresolvedMemberExpr.
      NumArgLabels : 16
    );
  
    SWIFT_INLINE_BITFIELD(OverloadSetRefExpr, Expr, 2,
      FunctionRefKind : 2
    );
  
    SWIFT_INLINE_BITFIELD(BooleanLiteralExpr, LiteralExpr, 1,
      Value : 1
    );
  
    SWIFT_INLINE_BITFIELD(MagicIdentifierLiteralExpr, LiteralExpr, 3+1,
      Kind : 3,
      StringEncoding : 1
    );
  
    SWIFT_INLINE_BITFIELD_FULL(ObjectLiteralExpr, LiteralExpr, 3+1+1+16,
      LitKind : 3,
      /// Whether the ObjectLiteralExpr also has source locations for the argument
      /// label.
      HasArgLabelLocs : 1,
      /// Whether the last argument is a trailing closure.
      HasTrailingClosure : 1,
      : NumPadBits,
      /// # of argument labels stored after the ObjectLiteralExpr.
      NumArgLabels : 16
    );
  
    SWIFT_INLINE_BITFIELD(AbstractClosureExpr, Expr, (16-NumExprBits)+16,
      : 16 - NumExprBits, // Align and leave room for subclasses
      Discriminator : 16
    );
  
    SWIFT_INLINE_BITFIELD(ClosureExpr, AbstractClosureExpr, 1,
      /// True if closure parameters were synthesized from anonymous closure
      /// variables.
      HasAnonymousClosureVars : 1
    );
  
    SWIFT_INLINE_BITFIELD_FULL(BindOptionalExpr, Expr, 16,
      : NumPadBits,
      Depth : 16
    );
  
    SWIFT_INLINE_BITFIELD_EMPTY(ImplicitConversionExpr, Expr);
  
    SWIFT_INLINE_BITFIELD_FULL(TupleShuffleExpr, ImplicitConversionExpr, 2+16+16+16,
      TypeImpact : 2,
      : NumPadBits,
      NumCallerDefaultArgs : 16,
      /// This contains an entry for each element in the Expr type.  Each element
      /// specifies which index from the SubExpr that the destination element gets.
      /// If the element value is DefaultInitialize, then the destination value
      /// gets the default initializer for that tuple element value.
      NumElementMappings : 16,
      /// The arguments that are packed into the variadic element.
      NumVariadicArgs : 16
    );
  
    SWIFT_INLINE_BITFIELD(ForceValueExpr, Expr, 1,
      ForcedIUO : 1
    );
  
    SWIFT_INLINE_BITFIELD(InOutToPointerExpr, ImplicitConversionExpr, 1,
      IsNonAccessing : 1
    );
  
    SWIFT_INLINE_BITFIELD(ArrayToPointerExpr, ImplicitConversionExpr, 1,
      IsNonAccessing : 1
    );
  
    SWIFT_INLINE_BITFIELD_FULL(ErasureExpr, ImplicitConversionExpr, 32,
      : NumPadBits,
      NumConformances : 32
    );
  
    SWIFT_INLINE_BITFIELD_FULL(UnresolvedSpecializeExpr, Expr, 32,
      : NumPadBits,
      NumUnresolvedParams : 32
    );
  
    SWIFT_INLINE_BITFIELD_FULL(CaptureListExpr, Expr, 32,
      : NumPadBits,
      NumCaptures : 32
    );
  
    SWIFT_INLINE_BITFIELD(ApplyExpr, Expr, 1+1,
      ThrowsIsSet : 1,
      Throws : 1
    );
  
    SWIFT_INLINE_BITFIELD_FULL(CallExpr, ApplyExpr, 1+1+16,
      /// Whether the CallExpr also has source locations for the argument label.
      HasArgLabelLocs : 1,
      /// Whether the last argument is a trailing closure.
      HasTrailingClosure : 1,
      : NumPadBits,
      /// # of argument labels stored after the CallExpr.
      NumArgLabels : 16
    );
  
    enum { NumCheckedCastKindBits = 4 };
    SWIFT_INLINE_BITFIELD(CheckedCastExpr, Expr, NumCheckedCastKindBits,
      CastKind : NumCheckedCastKindBits
    );
    static_assert(unsigned(CheckedCastKind::Last_CheckedCastKind)
                    < (1 << NumCheckedCastKindBits),
                  "unable to fit a CheckedCastKind in the given number of bits");
  
    SWIFT_INLINE_BITFIELD_EMPTY(CollectionUpcastConversionExpr, Expr);
  
    SWIFT_INLINE_BITFIELD(ObjCSelectorExpr, Expr, 2,
      /// The selector kind.
      SelectorKind : 2
    );
  
    SWIFT_INLINE_BITFIELD(KeyPathExpr, Expr, 1,
      /// Whether this is an ObjC stringified keypath.
      IsObjC : 1
    );
  
    SWIFT_INLINE_BITFIELD_FULL(SequenceExpr, Expr, 32,
      : NumPadBits,
      NumElements : 32
    );
  
    } Bits;
  
  private:
    /// Ty - This is the type of the expression.
    Type Ty;
   
  protected:
    Expr(ExprKind Kind, bool Implicit, Type Ty = Type()) : Ty(Ty) {
      Bits.OpaqueBits = 0;
      Bits.Expr.Kind = unsigned(Kind);
      Bits.Expr.Implicit = Implicit;
    }
  
  public:
    /// Return the kind of this expression.
    ExprKind getKind() const { return ExprKind(Bits.Expr.Kind); }
  
    /// Retrieve the name of the given expression kind.
    ///
    /// This name should only be used for debugging dumps and other
    /// developer aids, and should never be part of a diagnostic or exposed
    /// to the user of the compiler in any way.
    static StringRef getKindName(ExprKind K);
  
    /// getType - Return the type of this expression.
    Type getType() const { return Ty; }
  
    /// setType - Sets the type of this expression.
    void setType(Type T);
  
    /// Return the source range of the expression.
    SourceRange getSourceRange() const;
    
    /// getStartLoc - Return the location of the start of the expression.
    SourceLoc getStartLoc() const;
  
    /// Retrieve the location of the last token of the expression.
    SourceLoc getEndLoc() const;
    
    /// getLoc - Return the caret location of this expression.
    SourceLoc getLoc() const;
  
  #define SWIFT_FORWARD_SOURCE_LOCS_TO(SUBEXPR) \
    SourceLoc getStartLoc() const { return (SUBEXPR)->getStartLoc(); } \
    SourceLoc getEndLoc() const { return (SUBEXPR)->getEndLoc(); } \
    SourceLoc getLoc() const { return (SUBEXPR)->getLoc(); } \
    SourceRange getSourceRange() const { return (SUBEXPR)->getSourceRange(); }
  
    SourceLoc TrailingSemiLoc;
  
    /// getSemanticsProvidingExpr - Find the smallest subexpression
    /// which obeys the property that evaluating it is exactly
    /// equivalent to evaluating this expression.
    ///
    /// Looks through parentheses.  Would not look through something
    /// like '(foo(), x:bar(), baz()).x'.
    Expr *getSemanticsProvidingExpr();
  
    const Expr *getSemanticsProvidingExpr() const {
      return const_cast<Expr *>(this)->getSemanticsProvidingExpr();
    }
  
    /// getValueProvidingExpr - Find the smallest subexpression which is
    /// responsible for generating the value of this expression.
    /// Evaluating the result is not necessarily equivalent to
    /// evaluating this expression because of potential missing
    /// side-effects (which may influence the returned value).
    Expr *getValueProvidingExpr();
  
    const Expr *getValueProvidingExpr() const {
      return const_cast<Expr *>(this)->getValueProvidingExpr();
    }
  
    /// If this is a reference to an operator written as a member of a type (or
    /// extension thereof), return the underlying operator reference.
    DeclRefExpr *getMemberOperatorRef();
  
    /// This recursively walks the AST rooted at this expression.
    Expr *walk(ASTWalker &walker);
    Expr *walk(ASTWalker &&walker) { return walk(walker); }
  
    /// Enumerate each immediate child expression of this node, invoking the
    /// specific functor on it.  This ignores statements and other non-expression
    /// children.
    void forEachImmediateChildExpr(llvm::function_ref<Expr *(Expr *)> callback);
  
    /// Enumerate each expr node within this expression subtree, invoking the
    /// specific functor on it.  This ignores statements and other non-expression
    /// children, and if there is a closure within the expression, this does not
    /// walk into the body of it (unless it is single-expression).
    void forEachChildExpr(llvm::function_ref<Expr *(Expr *)> callback);
  
    /// Determine whether this expression refers to a type by name.
    ///
    /// This distinguishes static references to types, like Int, from metatype
    /// values, "someTy: Any.Type".
    bool isTypeReference(llvm::function_ref<Type(const Expr *)> getType =
                             [](const Expr *E) -> Type {
      return E->getType();
    }) const;
  
    /// Determine whether this expression refers to a statically-derived metatype.
    ///
    /// This implies `isTypeReference`, but also requires that the referenced type
    /// is not an archetype or dependent type.
    bool isStaticallyDerivedMetatype(
        llvm::function_ref<Type(const Expr *)> getType =
            [](const Expr *E) -> Type { return E->getType(); }) const;
  
    /// isImplicit - Determines whether this expression was implicitly-generated,
    /// rather than explicitly written in the AST.
    bool isImplicit() const {
      return Bits.Expr.Implicit;
    }
    void setImplicit(bool Implicit = true) {
      Bits.Expr.Implicit = Implicit;
    }
  
    /// Retrieves the declaration that is being referenced by this
    /// expression, if any.
    ConcreteDeclRef getReferencedDecl() const;
  
    /// Determine whether this expression is 'super', possibly converted to
    /// a base class.
    bool isSuperExpr() const;
  
    /// Returns whether the semantically meaningful content of this expression is
    /// an inout expression.
    ///
    /// FIXME(Remove InOutType): This should eventually sub-in for
    /// 'E->getType()->is<InOutType>()' in all cases.
    bool isSemanticallyInOutExpr() const {
      return getSemanticsProvidingExpr()->getKind() == ExprKind::InOut;
    }
    
    /// Returns false if this expression needs to be wrapped in parens when
    /// used inside of a any postfix expression, true otherwise.
    ///
    /// \param appendingPostfixOperator if the expression being
    /// appended is a postfix operator like '!' or '?'.
    bool canAppendPostfixExpression(bool appendingPostfixOperator = false) const;
  
    /// Returns true if this is an infix operator of some sort, including
    /// a builtin operator.
    bool isInfixOperator() const;
  
    /// Returns true if this is a reference to the implicit self of function.
    bool isSelfExprOf(const AbstractFunctionDecl *AFD,
                      bool sameBase = false) const;
  
    /// Produce a mapping from each subexpression to its parent
    /// expression, with the provided expression serving as the root of
    /// the parent map.
    llvm::DenseMap<Expr *, Expr *> getParentMap();
  
    /// Produce a mapping from each subexpression to its depth and parent,
    /// in the root expression. The root expression has depth 0, its children have
    /// depth 1, etc.
    llvm::DenseMap<Expr *, std::pair<unsigned, Expr *>> getDepthMap();
  
    /// Produce a mapping from each expression to its index according to a
    /// preorder traversal of the expressions. The parent has index 0, its first
    /// child has index 1, its second child has index 2 if the first child is a
    /// leaf node, etc.
    llvm::DenseMap<Expr *, unsigned> getPreorderIndexMap();
  
    LLVM_ATTRIBUTE_DEPRECATED(
        void dump() const LLVM_ATTRIBUTE_USED,
        "only for use within the debugger");
    void dump(raw_ostream &OS, unsigned Indent = 0) const;
    void dump(raw_ostream &OS, llvm::function_ref<Type(const Expr *)> getType,
              llvm::function_ref<Type(const TypeLoc &)> getTypeOfTypeLoc,
              unsigned Indent = 0) const;
    
    void print(ASTPrinter &Printer, const PrintOptions &Opts) const;
  
    // Only allow allocation of Exprs using the allocator in ASTContext
    // or by doing a placement new.
    void *operator new(size_t Bytes, ASTContext &C,
                       unsigned Alignment = alignof(Expr));
  
    // Make placement new and vanilla new/delete illegal for Exprs.
    void *operator new(size_t Bytes) throw() = delete;
    void operator delete(void *Data) throw() = delete;
  
    void *operator new(size_t Bytes, void *Mem) { 
      assert(Mem); 
      return Mem; 
    }
  };
  
  /// Helper class to capture trailing call argument labels and related
  /// information, for expression nodes that involve argument labels, trailing
  /// closures, etc.
  template<typename Derived>
  class TrailingCallArguments
      : private llvm::TrailingObjects<Derived, Identifier, SourceLoc> {
    // We need to friend TrailingObjects twice here to work around an MSVC bug.
    // If we have two functions of the same name with the parameter
    // typename TrailingObjectsIdentifier::template OverloadToken<T> where T is
    // different for each function, then MSVC reports a "member function already
    // defined or declared" error, which is incorrect.
    using TrailingObjectsIdentifier = llvm::TrailingObjects<Derived, Identifier>;
    friend TrailingObjectsIdentifier;
  
    using TrailingObjects = llvm::TrailingObjects<Derived, Identifier, SourceLoc>;
    friend TrailingObjects;
  
    Derived &asDerived() {
      return *static_cast<Derived *>(this);
    }
  
    const Derived &asDerived() const {
      return *static_cast<const Derived *>(this);
    }
  
    size_t numTrailingObjects(
        typename TrailingObjectsIdentifier::template OverloadToken<Identifier>)
        const {
      return asDerived().getNumArguments();
    }
  
    size_t numTrailingObjects(
        typename TrailingObjectsIdentifier::template OverloadToken<SourceLoc>)
        const {
      return asDerived().hasArgumentLabelLocs() ? asDerived().getNumArguments()
                                                : 0;
    }
  
    /// Retrieve the buffer containing the argument labels.
    MutableArrayRef<Identifier> getArgumentLabelsBuffer() {
      return { this->template getTrailingObjects<Identifier>(),
               asDerived().getNumArguments() };
    }
  
    /// Retrieve the buffer containing the argument label locations.
    MutableArrayRef<SourceLoc> getArgumentLabelLocsBuffer() {
      if (!asDerived().hasArgumentLabelLocs())
        return { };
      
      return { this->template getTrailingObjects<SourceLoc>(),
               asDerived().getNumArguments() };
    }
  
  protected:
    /// Determine the total size to allocate.
    static size_t totalSizeToAlloc(ArrayRef<Identifier> argLabels,
                                   ArrayRef<SourceLoc> argLabelLocs,
                                   bool hasTrailingClosure) {
      return TrailingObjects::template totalSizeToAlloc<Identifier, SourceLoc>(
          argLabels.size(), argLabelLocs.size());
    }
  
    /// Initialize the actual call arguments.
    void initializeCallArguments(ArrayRef<Identifier> argLabels,
                                 ArrayRef<SourceLoc> argLabelLocs,
                                 bool hasTrailingClosure) {
      if (!argLabels.empty()) {
        std::uninitialized_copy(argLabels.begin(), argLabels.end(),
                                this->template getTrailingObjects<Identifier>());
      }
      
      if (!argLabelLocs.empty())
        std::uninitialized_copy(argLabelLocs.begin(), argLabelLocs.end(),
                                this->template getTrailingObjects<SourceLoc>());
    }
  
  public:
    /// Retrieve the argument labels provided at the call site.
    ArrayRef<Identifier> getArgumentLabels() const {
      return { this->template getTrailingObjects<Identifier>(),
               asDerived().getNumArguments() };
    }
  
    /// Retrieve the buffer containing the argument label locations.
    ArrayRef<SourceLoc> getArgumentLabelLocs() const {
      if (!asDerived().hasArgumentLabelLocs())
        return { };
      
      return { this->template getTrailingObjects<SourceLoc>(),
               asDerived().getNumArguments() };
    }
  
    /// Retrieve the location of the ith argument label.
    SourceLoc getArgumentLabelLoc(unsigned i) const {
      auto locs = getArgumentLabelLocs();
      return i < locs.size() ? locs[i] : SourceLoc();
    }
  };
  
  /// ErrorExpr - Represents a semantically erroneous subexpression in the AST,
  /// typically this will have an ErrorType.
  class ErrorExpr : public Expr {
    SourceRange Range;
  public:
    ErrorExpr(SourceRange Range, Type Ty = Type())
      : Expr(ExprKind::Error, /*Implicit=*/true, Ty), Range(Range) {}
  
    SourceRange getSourceRange() const { return Range; }
    
    static bool classof(const Expr *E) {
      return E->getKind() == ExprKind::Error;
    }
  };
  
  /// CodeCompletionExpr - Represents the code completion token in the AST, this
  /// can help us preserve the context of the code completion position.
  class CodeCompletionExpr : public Expr {
    SourceRange Range;
  
  public:
    CodeCompletionExpr(SourceRange Range, Type Ty = Type())
        : Expr(ExprKind::CodeCompletion, /*Implicit=*/true, Ty), Range(Range) {}
  
    SourceRange getSourceRange() const { return Range; }
  
    static bool classof(const Expr *E) {
      return E->getKind() == ExprKind::CodeCompletion;
    }
  };
  
  /// LiteralExpr - Common base class between the literals.
  class LiteralExpr : public Expr {
  public:
    LiteralExpr(ExprKind Kind, bool Implicit) : Expr(Kind, Implicit) {}
    
    // Make an exact copy of this one AST node.
    LiteralExpr *
    shallowClone(ASTContext &Ctx,
                 llvm::function_ref<void(Expr *, Type)> setType,
                 llvm::function_ref<Type(const Expr *)> getType) const;
  
    static bool classof(const Expr *E) {
      return E->getKind() >= ExprKind::First_LiteralExpr &&
             E->getKind() <= ExprKind::Last_LiteralExpr;
    }
  };
  
  /// The 'nil' literal.
  ///
  class NilLiteralExpr : public LiteralExpr {
    SourceLoc Loc;
    ConcreteDeclRef Initializer;
  public:
    NilLiteralExpr(SourceLoc Loc, bool Implicit = false)
    : LiteralExpr(ExprKind::NilLiteral, Implicit), Loc(Loc) {
    }
    
    SourceRange getSourceRange() const {
      return Loc;
    }
  
    /// Retrieve the initializer that will be used to construct the 'nil'
    /// literal from the result of the initializer.
    ConcreteDeclRef getInitializer() const { return Initializer; }
  
    /// Set the initializer that will be used to construct the 'nil' literal.
    void setInitializer(ConcreteDeclRef initializer) {
      Initializer = initializer;
    }
    
    static bool classof(const Expr *E) {
      return E->getKind() == ExprKind::NilLiteral;
    }
  };
  
  /// Abstract base class for numeric literals, potentially with a sign.
  class NumberLiteralExpr : public LiteralExpr {
    /// The value of the literal as an ASTContext-owned string. Underscores must
    /// be stripped.
    StringRef Val;  // Use StringRef instead of APInt or APFloat, which leak.
    
  protected:
    SourceLoc MinusLoc;
    SourceLoc DigitsLoc;
    
  public:
     NumberLiteralExpr(ExprKind Kind,
                       StringRef Val, SourceLoc DigitsLoc, bool Implicit)
         : LiteralExpr(Kind, Implicit), Val(Val), DigitsLoc(DigitsLoc)
     {
       Bits.NumberLiteralExpr.IsNegative = false;
     }
    
    bool isNegative() const { return Bits.NumberLiteralExpr.IsNegative; }
    void setNegative(SourceLoc Loc) {
      MinusLoc = Loc;
      Bits.NumberLiteralExpr.IsNegative = true;
    }
  
    StringRef getDigitsText() const { return Val; }
  
    SourceRange getSourceRange() const {
      if (isNegative())
        return { MinusLoc, DigitsLoc };
      else
        return DigitsLoc;
    }
  
    SourceLoc getMinusLoc() const {
      return MinusLoc;
    }
  
    SourceLoc getDigitsLoc() const {
      return DigitsLoc;
    }
  
    static bool classof(const Expr *E) {
      return E->getKind() >= ExprKind::First_NumberLiteralExpr
        && E->getKind() <= ExprKind::Last_NumberLiteralExpr;
    }
  };
  
    
  /// Integer literal with a '+' or '-' sign, like '+4' or '- 2'.
  ///
  /// After semantic analysis assigns types, this is guaranteed to only have
  /// a BuiltinIntegerType.
  class IntegerLiteralExpr : public NumberLiteralExpr {
  public:
    IntegerLiteralExpr(StringRef Val, SourceLoc DigitsLoc, bool Implicit = false)
        : NumberLiteralExpr(ExprKind::IntegerLiteral,
                            Val, DigitsLoc, Implicit)
    {}
  
    /// Returns a new integer literal expression with the given value.
    /// \p C The AST context.
    /// \p value The integer value.
    /// \return An implicit integer literal expression which evaluates to the value.
    static IntegerLiteralExpr *
    createFromUnsigned(ASTContext &C, unsigned value);
  
    /// Returns the value of the literal, appropriately constructed in the
    /// target type.
    APInt getValue() const;
  
    /// Returns the raw value of the literal without any truncation.
    APInt getRawValue() const;
  
    static bool classof(const Expr *E) {
      return E->getKind() == ExprKind::IntegerLiteral;
    }
  };
  
  /// FloatLiteralExpr - Floating point literal, like '4.0'.  After semantic
  /// analysis assigns types, this is guaranteed to only have a
  /// BuiltinFloatingPointType.
  class FloatLiteralExpr : public NumberLiteralExpr {
  public:
    FloatLiteralExpr(StringRef Val, SourceLoc Loc, bool Implicit = false)
      : NumberLiteralExpr(ExprKind::FloatLiteral, Val, Loc, Implicit)
    {}
    
    APFloat getValue() const;
    static APFloat getValue(StringRef Text, const llvm::fltSemantics &Semantics,
                            bool Negative);
    
    static bool classof(const Expr *E) {
      return E->getKind() == ExprKind::FloatLiteral;
    }
  };
  
  /// A Boolean literal ('true' or 'false')
  ///
  class BooleanLiteralExpr : public LiteralExpr {
    SourceLoc Loc;
    ConcreteDeclRef BuiltinInitializer;
    ConcreteDeclRef Initializer;
  
  public:
    BooleanLiteralExpr(bool Value, SourceLoc Loc, bool Implicit = false)
      : LiteralExpr(ExprKind::BooleanLiteral, Implicit), Loc(Loc) {
      Bits.BooleanLiteralExpr.Value = Value;
    }
  
    /// Retrieve the Boolean value of this literal.
    bool getValue() const { return Bits.BooleanLiteralExpr.Value; }
  
    SourceRange getSourceRange() const {
      return Loc;
    }
  
    /// Retrieve the builtin initializer that will be used to construct the
    /// boolean literal.
    ///
    /// Any type-checked boolean literal will have a builtin initializer, which is
    /// called first to form a concrete Swift type.
    ConcreteDeclRef getBuiltinInitializer() const { return BuiltinInitializer; }
  
    /// Set the builtin initializer that will be used to construct the boolean
    /// literal.
    void setBuiltinInitializer(ConcreteDeclRef builtinInitializer) {
      BuiltinInitializer = builtinInitializer;
    }
  
    /// Retrieve the initializer that will be used to construct the boolean
    /// literal from the result of the initializer.
    ///
    /// Only boolean literals that have no builtin literal conformance will have
    /// this initializer, which will be called on the result of the builtin
    /// initializer.
    ConcreteDeclRef getInitializer() const { return Initializer; }
  
    /// Set the initializer that will be used to construct the boolean literal.
    void setInitializer(ConcreteDeclRef initializer) {
      Initializer = initializer;
    }
  
    static bool classof(const Expr *E) {
      return E->getKind() == ExprKind::BooleanLiteral;
    }
  };
    
  /// StringLiteralExpr - String literal, like '"foo"'.
  class StringLiteralExpr : public LiteralExpr {
    StringRef Val;
    SourceRange Range;
    ConcreteDeclRef BuiltinInitializer;
    ConcreteDeclRef Initializer;
  
  public:
    /// The encoding that should be used for the string literal.
    enum Encoding : unsigned {
      /// A UTF-8 string.
      UTF8,
  
      /// A UTF-16 string.
      UTF16,
  
      /// A single UnicodeScalar, passed as an integer.
      OneUnicodeScalar
    };
  
    StringLiteralExpr(StringRef Val, SourceRange Range, bool Implicit = false);
  
    StringRef getValue() const { return Val; }
    SourceRange getSourceRange() const { return Range; }
  
    /// Determine the encoding that should be used for this string literal.
    Encoding getEncoding() const {
      return static_cast<Encoding>(Bits.StringLiteralExpr.Encoding);
    }
  
    /// Set the encoding that should be used for this string literal.
    void setEncoding(Encoding encoding) {
      Bits.StringLiteralExpr.Encoding = static_cast<unsigned>(encoding);
    }
  
    bool isSingleUnicodeScalar() const {
      return Bits.StringLiteralExpr.IsSingleUnicodeScalar;
    }
  
    bool isSingleExtendedGraphemeCluster() const {
      return Bits.StringLiteralExpr.IsSingleExtendedGraphemeCluster;
    }
  
    /// Retrieve the builtin initializer that will be used to construct the string
    /// literal.
    ///
    /// Any type-checked string literal will have a builtin initializer, which is
    /// called first to form a concrete Swift type.
    ConcreteDeclRef getBuiltinInitializer() const { return BuiltinInitializer; }
  
    /// Set the builtin initializer that will be used to construct the string
    /// literal.
    void setBuiltinInitializer(ConcreteDeclRef builtinInitializer) {
      BuiltinInitializer = builtinInitializer;
    }
  
    /// Retrieve the initializer that will be used to construct the string
    /// literal from the result of the initializer.
    ///
    /// Only string literals that have no builtin literal conformance will have
    /// this initializer, which will be called on the result of the builtin
    /// initializer.
    ConcreteDeclRef getInitializer() const { return Initializer; }
  
    /// Set the initializer that will be used to construct the string literal.
    void setInitializer(ConcreteDeclRef initializer) {
      Initializer = initializer;
    }
  
    static bool classof(const Expr *E) {
      return E->getKind() == ExprKind::StringLiteral;
    }
  };
  
  /// Runs a series of statements which use or modify \c SubExpr
  /// before it is given to the rest of the expression.
  ///
  /// \c Body should begin with a \c VarDecl; this defines the variable
  /// \c TapExpr will initialize at the beginning and read a result
  /// from at the end. \c TapExpr creates a separate scope, then
  /// assigns the result of \c SubExpr to the variable and runs \c Body
  /// in it, returning the value of the variable after the \c Body runs.
  ///
  /// (The design here could be a bit cleaner, particularly where the VarDecl
  /// is concerned.)
  class TapExpr : public Expr {
    Expr *SubExpr;
    BraceStmt *Body;
  
  public:
    TapExpr(Expr *SubExpr, BraceStmt *Body);
  
    Expr * getSubExpr() const { return SubExpr; }
    void setSubExpr(Expr * se) { SubExpr = se; }
  
    /// The variable which will be accessed and possibly modified by
    /// the \c Body. This is the first \c ASTNode in the \c Body.
    VarDecl * getVar() const;
  
    BraceStmt * getBody() const { return Body; }
    void setBody(BraceStmt * b) { Body = b; }
  
    SourceLoc getLoc() const { return SourceLoc(); }
    SourceRange getSourceRange() const { return SourceRange(); }
  
    static bool classof(const Expr *E) {
      return E->getKind() == ExprKind::Tap;
    }
  };
  
  /// InterpolatedStringLiteral - An interpolated string literal.
  ///
  /// An interpolated string literal mixes expressions (which are evaluated and
  /// converted into string form) within a string literal.
  ///
  /// \code
  /// "[\(min)..\(max)]"
  /// \endcode
  class InterpolatedStringLiteralExpr : public LiteralExpr {
    /// Points at the beginning quote.
    SourceLoc Loc;
    TapExpr *AppendingExpr;
    Expr *SemanticExpr;
    
  public:
    InterpolatedStringLiteralExpr(SourceLoc Loc, unsigned LiteralCapacity, 
                                  unsigned InterpolationCount,
                                  TapExpr *AppendingExpr)
        : LiteralExpr(ExprKind::InterpolatedStringLiteral, /*Implicit=*/false),
          Loc(Loc), AppendingExpr(AppendingExpr), SemanticExpr() {
      Bits.InterpolatedStringLiteralExpr.InterpolationCount = InterpolationCount;
      Bits.InterpolatedStringLiteralExpr.LiteralCapacity = LiteralCapacity;
    }
  
    /// Retrieve the value of the literalCapacity parameter to the
    /// initializer.
    unsigned getLiteralCapacity() const {
      return Bits.InterpolatedStringLiteralExpr.LiteralCapacity;
    }
  
    /// Retrieve the value of the interpolationCount parameter to the
    /// initializer.
    unsigned getInterpolationCount() const {
      return Bits.InterpolatedStringLiteralExpr.InterpolationCount;
    }
  
    /// A block containing expressions which call
    /// \c StringInterpolationProtocol methods to append segments to the
    /// string interpolation. The first node in \c Body should be an uninitialized
    /// \c VarDecl; the other statements should append to it.
    TapExpr * getAppendingExpr() const { return AppendingExpr; }
    void setAppendingExpr(TapExpr * AE) { AppendingExpr = AE; }
    
    /// Retrieve the expression that actually evaluates the resulting
    /// string, typically with a series of '+' operations.
    Expr *getSemanticExpr() const { return SemanticExpr; }
    void setSemanticExpr(Expr *SE) { SemanticExpr = SE; }
    
    SourceLoc getStartLoc() const {
      return Loc;
    }
    SourceLoc getEndLoc() const {
      // SourceLocs are token based, and the interpolated string is one string
      // token, so the range should be (Start == End).
      return Loc;
    }
  
    /// Call the \c callback with information about each segment in turn.
    void forEachSegment(ASTContext &Ctx,
                        llvm::function_ref<void(bool, CallExpr *)> callback);
    
    static bool classof(const Expr *E) {
      return E->getKind() == ExprKind::InterpolatedStringLiteral;
    }
  };
    
  /// MagicIdentifierLiteralExpr - A magic identifier like #file which expands
  /// out to a literal at SILGen time.
  class MagicIdentifierLiteralExpr : public LiteralExpr {
  public:
    enum Kind : unsigned {
      File, Line, Column, Function, DSOHandle
    };
  private:
    SourceLoc Loc;
    ConcreteDeclRef BuiltinInitializer;
    ConcreteDeclRef Initializer;
  
  public:
    MagicIdentifierLiteralExpr(Kind kind, SourceLoc loc, bool implicit = false)
      : LiteralExpr(ExprKind::MagicIdentifierLiteral, implicit), Loc(loc) {
      Bits.MagicIdentifierLiteralExpr.Kind = static_cast<unsigned>(kind);
      Bits.MagicIdentifierLiteralExpr.StringEncoding
        = static_cast<unsigned>(StringLiteralExpr::UTF8);
    }
    
    Kind getKind() const {
      return static_cast<Kind>(Bits.MagicIdentifierLiteralExpr.Kind);
    }
  
    bool isFile() const { return getKind() == File; }
    bool isFunction() const { return getKind() == Function; }
    bool isLine() const { return getKind() == Line; }
    bool isColumn() const { return getKind() == Column; }
    
    bool isString() const {
      switch (getKind()) {
      case File:
      case Function:
        return true;
      case Line:
      case Column:
      case DSOHandle:
        return false;
      }
      llvm_unreachable("bad Kind");
    }
  
    SourceRange getSourceRange() const { return Loc; }
  
    // For a magic identifier that produces a string literal, retrieve the
    // encoding for that string literal.
    StringLiteralExpr::Encoding getStringEncoding() const {
      assert(isString() && "Magic identifier literal has non-string encoding");
      return static_cast<StringLiteralExpr::Encoding>(
               Bits.MagicIdentifierLiteralExpr.StringEncoding);
    }
  
    // For a magic identifier that produces a string literal, set the encoding
    // for the string literal.
    void setStringEncoding(StringLiteralExpr::Encoding encoding) {
      assert(isString() && "Magic identifier literal has non-string encoding");
      Bits.MagicIdentifierLiteralExpr.StringEncoding
        = static_cast<unsigned>(encoding);
    }
  
    /// Retrieve the builtin initializer that will be used to construct the string
    /// literal.
    ///
    /// Any type-checked string literal will have a builtin initializer, which is
    /// called first to form a concrete Swift type.
    ConcreteDeclRef getBuiltinInitializer() const {
      assert(isString() && "Magic identifier literal is not a string");
      return BuiltinInitializer;
    }
  
    /// Set the builtin initializer that will be used to construct the string
    /// literal.
    void setBuiltinInitializer(ConcreteDeclRef builtinInitializer) {
      assert(isString() && "Magic identifier literal is not a string");
      BuiltinInitializer = builtinInitializer;
    }
  
    /// Retrieve the initializer that will be used to construct the string
    /// literal from the result of the initializer.
    ///
    /// Only string literals that have no builtin literal conformance will have
    /// this initializer, which will be called on the result of the builtin
    /// initializer.
    ConcreteDeclRef getInitializer() const {
      assert(isString() && "Magic identifier literal is not a string");
      return Initializer;
    }
  
    /// Set the initializer that will be used to construct the string literal.
    void setInitializer(ConcreteDeclRef initializer) {
      assert(isString() && "Magic identifier literal is not a string");
      Initializer = initializer;
    }
  
    static bool classof(const Expr *E) {
      return E->getKind() == ExprKind::MagicIdentifierLiteral;
    }
  };
  
  // ObjectLiteralExpr - An expression of the form
  // '#colorLiteral(red: 1, blue: 0, green: 0, alpha: 1)' with a name and a list
  // argument. The components of the list argument are meant to be themselves
  // constant.
  class ObjectLiteralExpr final
      : public LiteralExpr,
        public TrailingCallArguments<ObjectLiteralExpr> {
  public:
    /// The kind of object literal.
    enum LiteralKind : unsigned {
  #define POUND_OBJECT_LITERAL(Name, Desc, Proto) Name,
  #include "swift/Syntax/TokenKinds.def"
    };
  
  private:
    Expr *Arg;
    Expr *SemanticExpr;
    SourceLoc PoundLoc;
  
    ObjectLiteralExpr(SourceLoc PoundLoc, LiteralKind LitKind,
                      Expr *Arg,
                      ArrayRef<Identifier> argLabels,
                      ArrayRef<SourceLoc> argLabelLocs,
                      bool hasTrailingClosure,
                      bool implicit);
  
  public:
    /// Create a new object literal expression.
    ///
    /// Note: prefer to use the second entry point, which separates out
    /// arguments/labels/etc.
    static ObjectLiteralExpr *
    create(ASTContext &ctx, SourceLoc poundLoc, LiteralKind kind, Expr *arg,
           bool implicit, llvm::function_ref<Type(const Expr *)> getType);
  
    /// Create a new object literal expression.
    static ObjectLiteralExpr *create(ASTContext &ctx, SourceLoc poundLoc,
                                     LiteralKind kind,
                                     SourceLoc lParenLoc,
                                     ArrayRef<Expr *> args,
                                     ArrayRef<Identifier> argLabels,
                                     ArrayRef<SourceLoc> argLabelLocs,
                                     SourceLoc rParenLoc,
                                     Expr *trailingClosure,
                                     bool implicit);
  
    LiteralKind getLiteralKind() const {
      return static_cast<LiteralKind>(Bits.ObjectLiteralExpr.LitKind);
    }
  
    Expr *getArg() const { return Arg; }
    void setArg(Expr *arg) { Arg = arg; }
  
    unsigned getNumArguments() const {
      return Bits.ObjectLiteralExpr.NumArgLabels;
    }
    bool hasArgumentLabelLocs() const {
      return Bits.ObjectLiteralExpr.HasArgLabelLocs;
    }
  
    /// Whether this call with written with a trailing closure.
    bool hasTrailingClosure() const {
      return Bits.ObjectLiteralExpr.HasTrailingClosure;
    }
  
    Expr *getSemanticExpr() const { return SemanticExpr; }
    void setSemanticExpr(Expr *expr) { SemanticExpr = expr; }
  
    SourceLoc getSourceLoc() const { return PoundLoc; }
    SourceRange getSourceRange() const { 
      return SourceRange(PoundLoc, Arg->getEndLoc());
    }
  
    /// Return the string form of the literal name.
    StringRef getLiteralKindRawName() const;
  
    StringRef getLiteralKindPlainName() const;
  
    static bool classof(const Expr *E) {
      return E->getKind() == ExprKind::ObjectLiteral;
    }
  };
  
  /// DiscardAssignmentExpr - A '_' in the left-hand side of an assignment, which
  /// discards the corresponding tuple element on the right-hand side.
  class DiscardAssignmentExpr : public Expr {
    SourceLoc Loc;
  
  public:
    DiscardAssignmentExpr(SourceLoc Loc, bool Implicit)
      : Expr(ExprKind::DiscardAssignment, Implicit), Loc(Loc) {}
    
    SourceRange getSourceRange() const { return Loc; }
    SourceLoc getLoc() const { return Loc; }
    
    static bool classof(const Expr *E) {
      return E->getKind() == ExprKind::DiscardAssignment;
    }
  };
  
  /// DeclRefExpr - A reference to a value, "x".
  class DeclRefExpr : public Expr {
    /// The declaration pointer.
    ConcreteDeclRef D;
    DeclNameLoc Loc;
  
  public:
    DeclRefExpr(ConcreteDeclRef D, DeclNameLoc Loc, bool Implicit,
                AccessSemantics semantics = AccessSemantics::Ordinary,
                Type Ty = Type())
      : Expr(ExprKind::DeclRef, Implicit, Ty), D(D), Loc(Loc) {
      Bits.DeclRefExpr.Semantics = (unsigned) semantics;
      Bits.DeclRefExpr.FunctionRefKind =
        static_cast<unsigned>(Loc.isCompound() ? FunctionRefKind::Compound
                                               : FunctionRefKind::Unapplied);
    }
  
    /// Retrieve the declaration to which this expression refers.
    ValueDecl *getDecl() const {
      return getDeclRef().getDecl();
    }
  
    /// Return true if this access is direct, meaning that it does not call the
    /// getter or setter.
    AccessSemantics getAccessSemantics() const {
      return (AccessSemantics) Bits.DeclRefExpr.Semantics;
    }
  
    /// Retrieve the concrete declaration reference.
    ConcreteDeclRef getDeclRef() const {
      return D;
    }
  
    SourceRange getSourceRange() const { return Loc.getSourceRange(); }
    SourceLoc getLoc() const { return Loc.getBaseNameLoc(); }
    DeclNameLoc getNameLoc() const { return Loc; }
  
    /// Retrieve the kind of function reference.
    FunctionRefKind getFunctionRefKind() const {
      return static_cast<FunctionRefKind>(Bits.DeclRefExpr.FunctionRefKind);
    }
  
    /// Set the kind of function reference.
    void setFunctionRefKind(FunctionRefKind refKind) {
      Bits.DeclRefExpr.FunctionRefKind = static_cast<unsigned>(refKind);
    }
  
    static bool classof(const Expr *E) {
      return E->getKind() == ExprKind::DeclRef;
    }
  };
    
  /// A reference to 'super'. References to members of 'super' resolve to members
  /// of a superclass of 'self'.
  class SuperRefExpr : public Expr {
    VarDecl *Self;
    SourceLoc Loc;
    
  public:
    SuperRefExpr(VarDecl *Self, SourceLoc Loc, bool Implicit,
                 Type SuperTy = Type())
      : Expr(ExprKind::SuperRef, Implicit, SuperTy), Self(Self), Loc(Loc) {}
    
    VarDecl *getSelf() const { return Self; }
    
    SourceLoc getSuperLoc() const { return Loc; }
    SourceRange getSourceRange() const { return Loc; }
    
    static bool classof(const Expr *E) {
      return E->getKind() == ExprKind::SuperRef;
    }
  };
  
  /// A reference to a type in expression context, spelled out as a TypeLoc. Sema
  /// forms this expression as a result of name binding.  This always has
  /// MetaTypetype.
  class TypeExpr : public Expr {
    TypeLoc Info;
    TypeExpr(Type Ty);
  public:
    // Create a TypeExpr with location information.
    TypeExpr(TypeLoc Ty);
  
    // The type of a TypeExpr is always a metatype type.  Return the instance
    // type, ErrorType if an error, or null if not set yet.
    Type getInstanceType(llvm::function_ref<bool(const Expr *)> hasType =
                             [](const Expr *E) -> bool { return !!E->getType(); },
                         llvm::function_ref<Type(const Expr *)> getType =
                             [](const Expr *E) -> Type {
                           return E->getType();
                         }) const;
  
    // Create an implicit TypeExpr, which has no location information.
    static TypeExpr *createImplicit(Type Ty, ASTContext &C) {
      return new (C) TypeExpr(Ty);
    }
  
    // Create an implicit TypeExpr, with location information even though it
    // shouldn't have one.  This is presently used to work around other location
    // processing bugs.  If you have an implicit location, use createImplicit.
    static TypeExpr *createImplicitHack(SourceLoc Loc, Type Ty, ASTContext &C);
  
    
    /// Create a TypeExpr for a TypeDecl at the specified location.
    static TypeExpr *createForDecl(SourceLoc Loc, TypeDecl *D,
                                   DeclContext *DC,
                                   bool isImplicit);
  
    /// Create a TypeExpr for a member TypeDecl of the given parent TypeDecl.
    static TypeExpr *createForMemberDecl(SourceLoc ParentNameLoc,
                                         TypeDecl *Parent,
                                         SourceLoc NameLoc,
                                         TypeDecl *Decl);
  
    /// Create a TypeExpr for a member TypeDecl of the given parent IdentTypeRepr.
    static TypeExpr *createForMemberDecl(IdentTypeRepr *ParentTR,
                                         SourceLoc NameLoc,
                                         TypeDecl *Decl);
  
    /// Create a TypeExpr from an IdentTypeRepr with the given arguments applied
    /// at the specified location.
    ///
    /// Returns nullptr if the reference cannot be formed, which is a hack due
    /// to limitations in how we model generic typealiases.
    static TypeExpr *createForSpecializedDecl(IdentTypeRepr *ParentTR,
                                              ArrayRef<TypeRepr*> Args,
                                              SourceRange AngleLocs,
                                              ASTContext &C);
  
    TypeLoc &getTypeLoc() { return Info; }
    TypeLoc getTypeLoc() const { return Info; }
    TypeRepr *getTypeRepr() const { return Info.getTypeRepr(); }
    // NOTE: TypeExpr::getType() returns the type of the expr node, which is the
    // metatype of what is stored as an operand type.
    
    SourceRange getSourceRange() const { return Info.getSourceRange(); }
    // TODO: optimize getStartLoc() and getEndLoc() when TypeLoc allows it.
  
    static bool classof(const Expr *E) {
      return E->getKind() == ExprKind::Type;
    }
  };
    
    
  
  /// A reference to another initializer from within a constructor body,
  /// either to a delegating initializer or to a super.init invocation.
  /// For a reference type, this semantically references a different constructor
  /// entry point, called the 'initializing constructor', from the 'allocating
  /// constructor' entry point referenced by a 'new' expression.
  class OtherConstructorDeclRefExpr : public Expr {
    ConcreteDeclRef Ctor;
    DeclNameLoc Loc;
    
  public:
    OtherConstructorDeclRefExpr(ConcreteDeclRef Ctor, DeclNameLoc Loc,
                                bool Implicit, Type Ty = {})
      : Expr(ExprKind::OtherConstructorDeclRef, Implicit, Ty),
        Ctor(Ctor), Loc(Loc)
    {}
    
    ConstructorDecl *getDecl() const;
    ConcreteDeclRef getDeclRef() const { return Ctor; }
  
    SourceLoc getLoc() const { return Loc.getBaseNameLoc(); }
    DeclNameLoc getConstructorLoc() const { return Loc; }
    SourceRange getSourceRange() const { return Loc.getSourceRange(); }
    
    static bool classof(const Expr *E) {
      return E->getKind() == ExprKind::OtherConstructorDeclRef;
    }
  };
  
  /// OverloadSetRefExpr - A reference to an overloaded set of values with a
  /// single name.
  ///
  /// This is an abstract class that covers the various different kinds of
  /// overload sets.
  class OverloadSetRefExpr : public Expr {
    ArrayRef<ValueDecl*> Decls;
  
  protected:
    OverloadSetRefExpr(ExprKind Kind, ArrayRef<ValueDecl*> decls,
                       FunctionRefKind functionRefKind, bool Implicit, Type Ty)
        : Expr(Kind, Implicit, Ty), Decls(decls) {
      Bits.OverloadSetRefExpr.FunctionRefKind =
        static_cast<unsigned>(functionRefKind);
    }
  
  public:
    ArrayRef<ValueDecl*> getDecls() const { return Decls; }
  
    void setDecls(ArrayRef<ValueDecl *> domain) {
      Decls = domain;
    }
  
    /// getBaseType - Determine the type of the base object provided for the
    /// given overload set, which is only non-null when dealing with an overloaded
    /// member reference.
    Type getBaseType() const;
  
    /// hasBaseObject - Determine whether this overloaded expression has a
    /// concrete base object (which is not a metatype).
    bool hasBaseObject() const;
  
    /// Retrieve the kind of function reference.
    FunctionRefKind getFunctionRefKind() const {
      return static_cast<FunctionRefKind>(
               Bits.OverloadSetRefExpr.FunctionRefKind);
    }
  
    /// Set the kind of function reference.
    void setFunctionRefKind(FunctionRefKind refKind) {
      Bits.OverloadSetRefExpr.FunctionRefKind = static_cast<unsigned>(refKind);
    }
  
    static bool classof(const Expr *E) {
      return E->getKind() >= ExprKind::First_OverloadSetRefExpr &&
             E->getKind() <= ExprKind::Last_OverloadSetRefExpr;
    }
  };
  
  /// OverloadedDeclRefExpr - A reference to an overloaded name that should
  /// eventually be resolved (by overload resolution) to a value reference.
  class OverloadedDeclRefExpr final : public OverloadSetRefExpr {
    DeclNameLoc Loc;
  
  public:
    OverloadedDeclRefExpr(ArrayRef<ValueDecl*> Decls, DeclNameLoc Loc,
                          FunctionRefKind functionRefKind,
                          bool Implicit, Type Ty = Type())
        : OverloadSetRefExpr(ExprKind::OverloadedDeclRef, Decls, functionRefKind,
                             Implicit, Ty),
          Loc(Loc) {
    }
    
    DeclNameLoc getNameLoc() const { return Loc; }
    SourceLoc getLoc() const { return Loc.getBaseNameLoc(); }
    SourceRange getSourceRange() const { return Loc.getSourceRange(); }
  
    static bool classof(const Expr *E) {
      return E->getKind() == ExprKind::OverloadedDeclRef;
    }
  };
  
  /// UnresolvedDeclRefExpr - This represents use of an undeclared identifier,
  /// which may ultimately be a use of something that hasn't been defined yet, it
  /// may be a use of something that got imported (which will be resolved during
  /// sema), or may just be a use of an unknown identifier.
  ///
  class UnresolvedDeclRefExpr : public Expr {
    DeclName Name;
    DeclNameLoc Loc;
  
  public:
    UnresolvedDeclRefExpr(DeclName name, DeclRefKind refKind, DeclNameLoc loc)
        : Expr(ExprKind::UnresolvedDeclRef, /*Implicit=*/loc.isInvalid()),
          Name(name), Loc(loc) {
      Bits.UnresolvedDeclRefExpr.DeclRefKind = static_cast<unsigned>(refKind);
      Bits.UnresolvedDeclRefExpr.FunctionRefKind =
        static_cast<unsigned>(Loc.isCompound() ? FunctionRefKind::Compound
                                               : FunctionRefKind::Unapplied);
    }
    
    bool hasName() const { return static_cast<bool>(Name); }
    DeclName getName() const { return Name; }
  
    DeclRefKind getRefKind() const {
      return static_cast<DeclRefKind>(Bits.UnresolvedDeclRefExpr.DeclRefKind);
    }
  
    /// Retrieve the kind of function reference.
    FunctionRefKind getFunctionRefKind() const {
      return static_cast<FunctionRefKind>(
               Bits.UnresolvedDeclRefExpr.FunctionRefKind);
    }
  
    /// Set the kind of function reference.
    void setFunctionRefKind(FunctionRefKind refKind) {
      Bits.UnresolvedDeclRefExpr.FunctionRefKind = static_cast<unsigned>(refKind);
    }
  
    DeclNameLoc getNameLoc() const { return Loc; }
  
    SourceRange getSourceRange() const { return Loc.getSourceRange(); }
  
    static bool classof(const Expr *E) {
      return E->getKind() == ExprKind::UnresolvedDeclRef;
    }
  };
  
  /// LookupExpr - This abstract class represents 'a.b', 'a[]', etc where we
  /// are referring to a member of a type, such as a property, variable, etc.
  class LookupExpr : public Expr {
    Expr *Base;
    ConcreteDeclRef Member;
  
  protected:
    explicit LookupExpr(ExprKind Kind, Expr *base, ConcreteDeclRef member,
                            bool Implicit)
        : Expr(Kind, Implicit), Base(base), Member(member) {
      Bits.LookupExpr.IsSuper = false;
      assert(Base);
    }
  
  public:
    /// Retrieve the base of the expression.
    Expr *getBase() const { return Base; }
  
    /// Replace the base of the expression.
    void setBase(Expr *E) { Base = E; }
  
    /// Retrieve the member to which this access refers.
    ConcreteDeclRef getMember() const { return Member; }
  
    /// Determine whether the operation has a known underlying declaration or not.
    bool hasDecl() const { return static_cast<bool>(Member); }
    
    /// Retrieve the declaration that this /// operation refers to.
    /// Only valid when \c hasDecl() is true.
    ConcreteDeclRef getDecl() const {
      assert(hasDecl() && "No subscript declaration known!");
      return getMember();
    }
  
    /// Determine whether this reference refers to the superclass's property.
    bool isSuper() const { return Bits.LookupExpr.IsSuper; }
  
    /// Set whether this reference refers to the superclass's property.
    void setIsSuper(bool isSuper) { Bits.LookupExpr.IsSuper = isSuper; }
  
    static bool classof(const Expr *E) {
      return E->getKind() >= ExprKind::First_LookupExpr &&
             E->getKind() <= ExprKind::Last_LookupExpr;
    }
  };
  
  /// MemberRefExpr - This represents 'a.b' where we are referring to a member
  /// of a type, such as a property or variable.
  ///
  /// Note that methods found via 'dot' syntax are expressed as DotSyntaxCallExpr
  /// nodes, because 'a.f' is actually an application of 'a' (the implicit object
  /// argument) to the function 'f'.
  class MemberRefExpr : public LookupExpr {
    SourceLoc DotLoc;
    DeclNameLoc NameLoc;
    
  public:
    MemberRefExpr(Expr *base, SourceLoc dotLoc, ConcreteDeclRef member,
                  DeclNameLoc loc, bool Implicit,
                  AccessSemantics semantics = AccessSemantics::Ordinary);
    SourceLoc getDotLoc() const { return DotLoc; }
    DeclNameLoc getNameLoc() const { return NameLoc; }
    
    /// Return true if this member access is direct, meaning that it
    /// does not call the getter or setter.
    AccessSemantics getAccessSemantics() const {
      return (AccessSemantics) Bits.MemberRefExpr.Semantics;
    }
  
    SourceLoc getLoc() const { return NameLoc.getBaseNameLoc(); }
    SourceLoc getStartLoc() const {
      SourceLoc BaseStartLoc = getBase()->getStartLoc();
      if (BaseStartLoc.isInvalid() || NameLoc.isInvalid()) {
        return NameLoc.getBaseNameLoc();
      } else {
        return BaseStartLoc;
      }
    }
    SourceLoc getEndLoc() const {
      return NameLoc.getSourceRange().End;
    }
    
    static bool classof(const Expr *E) {
      return E->getKind() == ExprKind::MemberRef;
    }
  };
    
  /// Common base for expressions that involve dynamic lookup, which
  /// determines at runtime whether a particular method, property, or
  /// subscript is available.
  class DynamicLookupExpr : public LookupExpr {
  protected:
    explicit DynamicLookupExpr(ExprKind kind, ConcreteDeclRef member, Expr *base)
      : LookupExpr(kind, base, member, /*Implicit=*/false) { }
  
  public:
    static bool classof(const Expr *E) {
      return E->getKind() >= ExprKind::First_DynamicLookupExpr &&
             E->getKind() <= ExprKind::Last_DynamicLookupExpr;
    }
  };
  
  /// A reference to a member of an object that was found via dynamic lookup.
  ///
  /// A member found via dynamic lookup may not actually be available at runtime.
  /// Therefore, a reference to that member always returns an optional instance.
  /// Users can then propagate the optional (via ?) or assert that the member is
  /// always available (via !). For example:
  ///
  /// \code
  /// class C {
  ///   func @objc foo(i : Int) -> String { ... }
  /// };
  ///
  /// var x : AnyObject = <some value>
  /// print(x.foo!(17)) // x.foo has type ((i : Int) -> String)?
  /// \endcode
  class DynamicMemberRefExpr : public DynamicLookupExpr {
    SourceLoc DotLoc;
    DeclNameLoc NameLoc;
  
  public:
    DynamicMemberRefExpr(Expr *base, SourceLoc dotLoc,
                         ConcreteDeclRef member,
                         DeclNameLoc nameLoc)
      : DynamicLookupExpr(ExprKind::DynamicMemberRef, member, base),
        DotLoc(dotLoc), NameLoc(nameLoc) {
      }
  
    /// Retrieve the location of the member name.
    DeclNameLoc getNameLoc() const { return NameLoc; }
  
    /// Retrieve the location of the '.'.
    SourceLoc getDotLoc() const { return DotLoc; }
  
    SourceLoc getLoc() const { return NameLoc.getBaseNameLoc(); }
  
    SourceLoc getStartLoc() const {
      SourceLoc BaseStartLoc = getBase()->getStartLoc();
      if (BaseStartLoc.isInvalid() || NameLoc.isInvalid()) {
        return NameLoc.getBaseNameLoc();
      } else {
        return BaseStartLoc;
      }
    }
    SourceLoc getEndLoc() const { return NameLoc.getSourceRange().End; }
  
    static bool classof(const Expr *E) {
      return E->getKind() == ExprKind::DynamicMemberRef;
    }
  };
  
  /// A subscript on an object with dynamic lookup type.
  ///
  /// A subscript found via dynamic lookup may not actually be available
  /// at runtime.  Therefore, the result of performing the subscript
  /// operation always returns an optional instance.Users can then
  /// propagate the optional (via ?) or assert that the member is always
  /// available (via !). For example:
  ///
  /// \code
  /// class C {
  ///   @objc subscript (i : Int) -> String {
  ///     get {
  ///       ...
  ///     }
  ///   }
  /// };
  ///
  /// var x : AnyObject = <some value>
  /// print(x[27]! // x[27] has type String?
  /// \endcode
  class DynamicSubscriptExpr final
      : public DynamicLookupExpr,
        public TrailingCallArguments<DynamicSubscriptExpr> {
    friend TrailingCallArguments;
  
    Expr *Index;
  
    DynamicSubscriptExpr(Expr *base, Expr *index, ArrayRef<Identifier> argLabels,
                         ArrayRef<SourceLoc> argLabelLocs,
                         bool hasTrailingClosure, ConcreteDeclRef member,
                         bool implicit);
  
  public:
    /// Create a dynamic subscript.
    ///
    /// Note: do not create new callers to this entry point; use the entry point
    /// that takes separate index arguments.
    static DynamicSubscriptExpr *
    create(ASTContext &ctx, Expr *base, Expr *index, ConcreteDeclRef decl,
           bool implicit,
           llvm::function_ref<Type(const Expr *)> getType =
               [](const Expr *E) -> Type { return E->getType(); });
  
    /// Create a new dynamic subscript.
    static DynamicSubscriptExpr *create(ASTContext &ctx, Expr *base,
                                        SourceLoc lSquareLoc,
                                        ArrayRef<Expr *> indexArgs,
                                        ArrayRef<Identifier> indexArgLabels,
                                        ArrayRef<SourceLoc> indexArgLabelLocs,
                                        SourceLoc rSquareLoc,
                                        Expr *trailingClosure,
                                        ConcreteDeclRef decl,
                                        bool implicit);
  
    /// getIndex - Retrieve the index of the subscript expression, i.e., the
    /// "offset" into the base value.
    Expr *getIndex() const { return Index; }
    void setIndex(Expr *E) { Index = E; }
  
    unsigned getNumArguments() const {
      return Bits.DynamicSubscriptExpr.NumArgLabels;
    }
  
    bool hasArgumentLabelLocs() const {
      return Bits.DynamicSubscriptExpr.HasArgLabelLocs;
    }
  
    /// Whether this call with written with a trailing closure.
    bool hasTrailingClosure() const {
      return Bits.DynamicSubscriptExpr.HasTrailingClosure;
    }
  
    SourceLoc getLoc() const { return Index->getStartLoc(); }
  
    SourceLoc getStartLoc() const { return getBase()->getStartLoc(); }
    SourceLoc getEndLoc() const { return Index->getEndLoc(); }
  
    static bool classof(const Expr *E) {
      return E->getKind() == ExprKind::DynamicSubscript;
    }
  };
  
  /// UnresolvedMemberExpr - This represents '.foo', an unresolved reference to a
  /// member, which is to be resolved with context sensitive type information into
  /// bar.foo.  These always have unresolved type.
  class UnresolvedMemberExpr final
      : public Expr,
        public TrailingCallArguments<UnresolvedMemberExpr> {
    SourceLoc DotLoc;
    DeclNameLoc NameLoc;
    DeclName Name;
    Expr *Argument;
  
    UnresolvedMemberExpr(SourceLoc dotLoc, DeclNameLoc nameLoc,
                         DeclName name, Expr *argument,
                         ArrayRef<Identifier> argLabels,
                         ArrayRef<SourceLoc> argLabelLocs,
                         bool hasTrailingClosure,
                         bool implicit);
  
  public:
    /// Create a new unresolved member expression with no arguments.
    static UnresolvedMemberExpr *create(ASTContext &ctx, SourceLoc dotLoc,
                                        DeclNameLoc nameLoc, DeclName name,
                                        bool implicit);
  
    /// Create a new unresolved member expression.
    static UnresolvedMemberExpr *create(ASTContext &ctx, SourceLoc dotLoc,
                                        DeclNameLoc nameLoc, DeclName name,
                                        SourceLoc lParenLoc,
                                        ArrayRef<Expr *> args,
                                        ArrayRef<Identifier> argLabels,
                                        ArrayRef<SourceLoc> argLabelLocs,
                                        SourceLoc rParenLoc,
                                        Expr *trailingClosure,
                                        bool implicit);
  
    DeclName getName() const { return Name; }
    DeclNameLoc getNameLoc() const { return NameLoc; }
    SourceLoc getDotLoc() const { return DotLoc; }
    Expr *getArgument() const { return Argument; }
    void setArgument(Expr *argument) { Argument = argument; }
  
    /// Whether this reference has arguments.
    bool hasArguments() const {
      return Bits.UnresolvedMemberExpr.HasArguments;
    }
  
    unsigned getNumArguments() const {
      return Bits.UnresolvedMemberExpr.NumArgLabels;
    }
  
    bool hasArgumentLabelLocs() const {
      return Bits.UnresolvedMemberExpr.HasArgLabelLocs;
    }
  
    /// Whether this call with written with a trailing closure.
    bool hasTrailingClosure() const {
      return Bits.UnresolvedMemberExpr.HasTrailingClosure;
    }
  
    SourceLoc getLoc() const { return NameLoc.getBaseNameLoc(); }
  
    SourceLoc getStartLoc() const { return DotLoc; }
    SourceLoc getEndLoc() const {
      return (Argument ? Argument->getEndLoc() : NameLoc.getSourceRange().End);
    }
    
    static bool classof(const Expr *E) {
      return E->getKind() == ExprKind::UnresolvedMember;
    }
  };
  
  /// AnyTryExpr - An abstract superclass for 'try' and 'try!'.
  ///
  /// These are like IdentityExpr in some ways, but they're a bit too
  /// semantic differentiated to just always look through.
  class AnyTryExpr : public Expr {
    Expr *SubExpr;
    SourceLoc TryLoc;
  
  public:
    AnyTryExpr(ExprKind kind, SourceLoc tryLoc, Expr *sub,
               Type type, bool implicit)
      : Expr(kind, implicit, type), SubExpr(sub), TryLoc(tryLoc) {}
  
    SourceLoc getLoc() const { return SubExpr->getLoc(); }
    Expr *getSubExpr() const { return SubExpr; }
    void setSubExpr(Expr *E) { SubExpr = E; }
  
    SourceLoc getTryLoc() const { return TryLoc; }
  
    SourceLoc getStartLoc() const { return TryLoc; }
    SourceLoc getEndLoc() const { return getSubExpr()->getEndLoc(); }
  
    static bool classof(const Expr *e) {
      return e->getKind() >= ExprKind::First_AnyTryExpr
          && e->getKind() <= ExprKind::Last_AnyTryExpr;
    }
  };
  
  /// TryExpr - A 'try' surrounding an expression, marking that the
  /// expression contains code which might throw.
  ///
  /// getSemanticsProvidingExpr() looks through this because it doesn't
  /// provide the value and only very specific clients care where the
  /// 'try' was written.
  class TryExpr : public AnyTryExpr {
  public:
    TryExpr(SourceLoc tryLoc, Expr *sub, Type type = Type(),
            bool implicit = false)
      : AnyTryExpr(ExprKind::Try, tryLoc, sub, type, implicit) {}
  
    static bool classof(const Expr *e) {
      return e->getKind() == ExprKind::Try;
    }
  };
  
  /// ForceTryExpr - A 'try!' surrounding an expression, marking that
  /// the expression contains code which might throw, but that the code
  /// should dynamically assert if it does.
  class ForceTryExpr : public AnyTryExpr {
    SourceLoc ExclaimLoc;
  
  public:
    ForceTryExpr(SourceLoc tryLoc, Expr *sub, SourceLoc exclaimLoc,
                 Type type = Type(), bool implicit = false)
      : AnyTryExpr(ExprKind::ForceTry, tryLoc, sub, type, implicit),
        ExclaimLoc(exclaimLoc) {}
  
    SourceLoc getExclaimLoc() const { return ExclaimLoc; }
  
    static bool classof(const Expr *e) {
      return e->getKind() == ExprKind::ForceTry;
    }
  };
  
  /// A 'try?' surrounding an expression, marking that the expression contains
  /// code which might throw, and that the result should be injected into an
  /// Optional. If the code does throw, \c nil is produced.
  class OptionalTryExpr : public AnyTryExpr {
    SourceLoc QuestionLoc;
  
  public:
    OptionalTryExpr(SourceLoc tryLoc, Expr *sub, SourceLoc questionLoc,
                    Type type = Type(), bool implicit = false)
      : AnyTryExpr(ExprKind::OptionalTry, tryLoc, sub, type, implicit),
        QuestionLoc(questionLoc) {}
  
    SourceLoc getQuestionLoc() const { return QuestionLoc; }
  
    static bool classof(const Expr *e) {
      return e->getKind() == ExprKind::OptionalTry;
    }
  };
  
  /// An expression node that does not affect the evaluation of its subexpression.
  class IdentityExpr : public Expr {
    Expr *SubExpr;
    
  public:
    IdentityExpr(ExprKind kind,
                 Expr *subExpr, Type ty = Type(),
                 bool implicit = false)
      : Expr(kind, implicit, ty), SubExpr(subExpr)
    {}
    
    SourceLoc getLoc() const { return SubExpr->getLoc(); }
    Expr *getSubExpr() const { return SubExpr; }
    void setSubExpr(Expr *E) { SubExpr = E; }
    
    static bool classof(const Expr *E) {
      return E->getKind() >= ExprKind::First_IdentityExpr
          && E->getKind() <= ExprKind::Last_IdentityExpr;
    }
  };
    
  /// The '.self' pseudo-property, which has no effect except to
  /// satisfy the syntactic requirement that type values appear only as part of
  /// a property chain.
  class DotSelfExpr : public IdentityExpr {
    SourceLoc DotLoc;
    SourceLoc SelfLoc;
    
  public:
    DotSelfExpr(Expr *subExpr, SourceLoc dot, SourceLoc self,
                Type ty = Type())
      : IdentityExpr(ExprKind::DotSelf, subExpr, ty),
        DotLoc(dot), SelfLoc(self)
    {}
    
    SourceLoc getDotLoc() const { return DotLoc; }
    SourceLoc getSelfLoc() const { return SelfLoc; }
  
    SourceLoc getStartLoc() const { return getSubExpr()->getStartLoc(); }
    SourceLoc getEndLoc() const { return SelfLoc; }
    
    static bool classof(const Expr *E) {
      return E->getKind() == ExprKind::DotSelf;
    }
  };
    
  /// A parenthesized expression like '(x+x)'.  Syntactically,
  /// this is just a TupleExpr with exactly one element that has no label.
  /// Semantically, however, it serves only as grouping parentheses and
  /// does not form an expression of tuple type (unless the sub-expression
  /// has tuple type, of course).
  class ParenExpr : public IdentityExpr {
    SourceLoc LParenLoc, RParenLoc;
    
  public:
    ParenExpr(SourceLoc lploc, Expr *subExpr, SourceLoc rploc,
              bool hasTrailingClosure,
              Type ty = Type())
      : IdentityExpr(ExprKind::Paren, subExpr, ty),
        LParenLoc(lploc), RParenLoc(rploc) {
      Bits.ParenExpr.HasTrailingClosure = hasTrailingClosure;
      assert(lploc.isValid() == rploc.isValid() &&
             "Mismatched source location information");
    }
  
    SourceLoc getLParenLoc() const { return LParenLoc; }
    SourceLoc getRParenLoc() const { return RParenLoc; }
  
    // When the locations of the parens are invalid, ask our
    // subexpression for its source range instead.  This isn't a
    // hot path and so we don't both optimizing for it.
  
    SourceLoc getStartLoc() const {
      return (LParenLoc.isInvalid() ? getSubExpr()->getStartLoc() : LParenLoc);
    }
    SourceLoc getEndLoc() const {
      // If we have a trailing closure, our end point is the end of the
      // trailing closure.
      if (RParenLoc.isInvalid() || Bits.ParenExpr.HasTrailingClosure)
        return getSubExpr()->getEndLoc();
      return RParenLoc;
    }
  
    /// Whether this expression has a trailing closure as its argument.
    bool hasTrailingClosure() const { return Bits.ParenExpr.HasTrailingClosure; }
  
    static bool classof(const Expr *E) { return E->getKind() == ExprKind::Paren; }
  };
    
  /// TupleExpr - Parenthesized expressions like '(a: x+x)' and '(x, y, 4)'.  Also
  /// used to represent the operands to a binary operator.  Note that
  /// expressions like '(4)' are represented with a ParenExpr.
  class TupleExpr final : public Expr,
      private llvm::TrailingObjects<TupleExpr, Expr *, Identifier, SourceLoc> {
    friend TrailingObjects;
  
    SourceLoc LParenLoc;
    SourceLoc RParenLoc;
  
    size_t numTrailingObjects(OverloadToken<Expr *>) const {
      return getNumElements();
    }
    size_t numTrailingObjects(OverloadToken<Identifier>) const {
      return hasElementNames() ? getNumElements() : 0;
    }
    size_t numTrailingObjects(OverloadToken<SourceLoc>) const {
      return hasElementNames() ? getNumElements() : 0;
    }
  
    /// Retrieve the buffer containing the element names.
    MutableArrayRef<Identifier> getElementNamesBuffer() {
      if (!hasElementNames())
        return { };
  
      return { getTrailingObjects<Identifier>(), getNumElements() };
    }
  
    /// Retrieve the buffer containing the element name locations.
    MutableArrayRef<SourceLoc> getElementNameLocsBuffer() {
      if (!hasElementNameLocs())
        return { };
      
      return { getTrailingObjects<SourceLoc>(), getNumElements() };
    }
  
    TupleExpr(SourceLoc LParenLoc, ArrayRef<Expr *> SubExprs,
              ArrayRef<Identifier> ElementNames, 
              ArrayRef<SourceLoc> ElementNameLocs,
              SourceLoc RParenLoc, bool HasTrailingClosure, bool Implicit, 
              Type Ty);
  
  public:
    /// Create a tuple.
    static TupleExpr *create(ASTContext &ctx,
                             SourceLoc LParenLoc, 
                             ArrayRef<Expr *> SubExprs,
                             ArrayRef<Identifier> ElementNames, 
                             ArrayRef<SourceLoc> ElementNameLocs,
                             SourceLoc RParenLoc, bool HasTrailingClosure, 
                             bool Implicit, Type Ty = Type());
  
    /// Create an empty tuple.
    static TupleExpr *createEmpty(ASTContext &ctx, SourceLoc LParenLoc, 
                                  SourceLoc RParenLoc, bool Implicit);
  
    /// Create an implicit tuple with no source information.
    static TupleExpr *createImplicit(ASTContext &ctx, ArrayRef<Expr *> SubExprs,
                                     ArrayRef<Identifier> ElementNames);
  
    SourceLoc getLParenLoc() const { return LParenLoc; }
    SourceLoc getRParenLoc() const { return RParenLoc; }
  
    SourceRange getSourceRange() const;
  
    /// Whether this expression has a trailing closure as its argument.
    bool hasTrailingClosure() const { return Bits.TupleExpr.HasTrailingClosure; }
  
    /// Retrieve the elements of this tuple.
    MutableArrayRef<Expr*> getElements() {
      return { getTrailingObjects<Expr *>(), getNumElements() };
    }
  
    /// Retrieve the elements of this tuple.
    ArrayRef<Expr*> getElements() const {
      return { getTrailingObjects<Expr *>(), getNumElements() };
    }
    
    unsigned getNumElements() const { return Bits.TupleExpr.NumElements; }
    
    Expr *getElement(unsigned i) const {
      return getElements()[i];
    }
    void setElement(unsigned i, Expr *e) {
      getElements()[i] = e;
    }
  
    /// Whether this tuple has element names.
    bool hasElementNames() const { 
      return Bits.TupleExpr.HasElementNames;
    }
  
    /// Retrieve the element names for a tuple.
    ArrayRef<Identifier> getElementNames() const { 
      return const_cast<TupleExpr *>(this)->getElementNamesBuffer();
    }
    
    /// Retrieve the ith element name.
    Identifier getElementName(unsigned i) const {
      return hasElementNames() ? getElementNames()[i] : Identifier();
    }
    
    /// Whether this tuple has element name locations.
    bool hasElementNameLocs() const { 
      return Bits.TupleExpr.HasElementNameLocations;
    }
  
    /// Retrieve the locations of the element names for a tuple.
    ArrayRef<SourceLoc> getElementNameLocs() const {
      return const_cast<TupleExpr *>(this)->getElementNameLocsBuffer();
    }
  
    /// Retrieve the location of the ith label, if known.
    SourceLoc getElementNameLoc(unsigned i) const {
      if (hasElementNameLocs())
        return getElementNameLocs()[i];
      
      return SourceLoc();
    }
  
    static bool classof(const Expr *E) { return E->getKind() == ExprKind::Tuple; }
  };
  
  /// A collection literal expression.
  ///
  /// The subexpression is represented as a TupleExpr or ParenExpr and
  /// passed on to the appropriate semantics-providing conversion
  /// operation.
  class CollectionExpr : public Expr {
    SourceLoc LBracketLoc;
    SourceLoc RBracketLoc;
  
    Expr *SemanticExpr = nullptr;
  
    /// Retrieve the intrusive pointer storage from the subtype
    Expr *const *getTrailingObjectsPointer() const;
    Expr **getTrailingObjectsPointer() {
      const CollectionExpr *temp = this;
      return const_cast<Expr**>(temp->getTrailingObjectsPointer());
    }
  
    /// Retrieve the intrusive pointer storage from the subtype
    const SourceLoc *getTrailingSourceLocs() const;
    SourceLoc *getTrailingSourceLocs() {
      const CollectionExpr *temp = this;
      return const_cast<SourceLoc*>(temp->getTrailingSourceLocs());
    }
  
  protected:
    CollectionExpr(ExprKind Kind, SourceLoc LBracketLoc,
                   ArrayRef<Expr*> Elements, ArrayRef<SourceLoc> CommaLocs,
                   SourceLoc RBracketLoc, Type Ty)
      : Expr(Kind, /*Implicit=*/false, Ty),
        LBracketLoc(LBracketLoc), RBracketLoc(RBracketLoc) {
      Bits.CollectionExpr.IsTypeDefaulted = false;
      Bits.CollectionExpr.NumSubExprs = Elements.size();
      Bits.CollectionExpr.NumCommas = CommaLocs.size();
      assert(Bits.CollectionExpr.NumCommas == CommaLocs.size() && "Truncation");
      std::uninitialized_copy(Elements.begin(), Elements.end(),
                              getTrailingObjectsPointer());
      std::uninitialized_copy(CommaLocs.begin(), CommaLocs.end(),
                              getTrailingSourceLocs());
    }
  
  public:
  
    /// Retrieve the elements stored in the collection.
    ArrayRef<Expr *> getElements() const {
      return {getTrailingObjectsPointer(), Bits.CollectionExpr.NumSubExprs};
    }
    MutableArrayRef<Expr *> getElements() {
      return {getTrailingObjectsPointer(), Bits.CollectionExpr.NumSubExprs};
    }
    Expr *getElement(unsigned i) const { return getElements()[i]; }
    void setElement(unsigned i, Expr *E) { getElements()[i] = E; }
    unsigned getNumElements() const { return Bits.CollectionExpr.NumSubExprs; }
  
    /// Retrieve the comma source locations stored in the collection. Please note
    /// that trailing commas are currently allowed, and that invalid code may have
    /// stray or missing commas.
    MutableArrayRef<SourceLoc> getCommaLocs() {
      return {getTrailingSourceLocs(), static_cast<size_t>(Bits.CollectionExpr.NumCommas)};
    }
    ArrayRef<SourceLoc> getCommaLocs() const {
      return {getTrailingSourceLocs(), static_cast<size_t>(Bits.CollectionExpr.NumCommas)};
    }
    unsigned getNumCommas() const { return Bits.CollectionExpr.NumCommas; }
  
    bool isTypeDefaulted() const { return Bits.CollectionExpr.IsTypeDefaulted; }
    void setIsTypeDefaulted(bool value = true) {
      Bits.CollectionExpr.IsTypeDefaulted = value;
    }
  
    SourceLoc getLBracketLoc() const { return LBracketLoc; }
    SourceLoc getRBracketLoc() const { return RBracketLoc; }
    SourceRange getSourceRange() const {
      return SourceRange(LBracketLoc, RBracketLoc);
    }
    
    Expr *getSemanticExpr() const { return SemanticExpr; }
    void setSemanticExpr(Expr *e) { SemanticExpr = e; }
  
    static bool classof(const Expr *e) {
      return e->getKind() >= ExprKind::First_CollectionExpr &&
             e->getKind() <= ExprKind::Last_CollectionExpr;
    }
  
  };
   
  /// An array literal expression [a, b, c].
  class ArrayExpr final : public CollectionExpr,
      private llvm::TrailingObjects<ArrayExpr, Expr*, SourceLoc> {
    friend TrailingObjects;
    friend CollectionExpr;
  
    size_t numTrailingObjects(OverloadToken<Expr *>) const {
      return getNumElements();
    }
    size_t numTrailingObjects(OverloadToken<SourceLoc>) const {
      return getNumCommas();
    }
  
    ArrayExpr(SourceLoc LBracketLoc, ArrayRef<Expr*> Elements,
              ArrayRef<SourceLoc> CommaLocs,
              SourceLoc RBracketLoc, Type Ty)
    : CollectionExpr(ExprKind::Array, LBracketLoc, Elements, CommaLocs,
                     RBracketLoc, Ty) { }
  public:
    static ArrayExpr *create(ASTContext &C, SourceLoc LBracketLoc,
                             ArrayRef<Expr*> Elements,
                             ArrayRef<SourceLoc> CommaLocs,
                             SourceLoc RBracketLoc,
                             Type Ty = Type());
  
    static bool classof(const Expr *e) {
      return e->getKind() == ExprKind::Array;
    }
  };
  
  /// A dictionary literal expression [a : x, b : y, c : z].
  class DictionaryExpr final : public CollectionExpr,
      private llvm::TrailingObjects<DictionaryExpr, Expr*, SourceLoc> {
    friend TrailingObjects;
    friend CollectionExpr;
  
    size_t numTrailingObjects(OverloadToken<Expr *>) const {
      return getNumElements();
    }
    size_t numTrailingObjects(OverloadToken<SourceLoc>) const {
      return getNumCommas();
    }
  
    DictionaryExpr(SourceLoc LBracketLoc, ArrayRef<Expr*> Elements,
                   ArrayRef<SourceLoc> CommaLocs,
                   SourceLoc RBracketLoc, Type Ty)
      : CollectionExpr(ExprKind::Dictionary, LBracketLoc, Elements, CommaLocs,
                       RBracketLoc, Ty) { }
  public:
  
    static DictionaryExpr *create(ASTContext &C, SourceLoc LBracketLoc,
                                  ArrayRef<Expr*> Elements,
                                  ArrayRef<SourceLoc> CommaLocs,
                                  SourceLoc RBracketLoc,
                                  Type Ty = Type());
  
    static bool classof(const Expr *e) {
      return e->getKind() == ExprKind::Dictionary;
    }
  };
  
  /// Subscripting expressions like a[i] that refer to an element within a
  /// container.
  ///
  /// There is no built-in subscripting in the language. Rather, a fully
  /// type-checked and well-formed subscript expression refers to a subscript
  /// declaration, which provides a getter and (optionally) a setter that will
  /// be used to perform reads/writes.
  class SubscriptExpr final : public LookupExpr,
                              public TrailingCallArguments<SubscriptExpr> {
    friend TrailingCallArguments;
  
    Expr *Index;
  
    SubscriptExpr(Expr *base, Expr *index, ArrayRef<Identifier> argLabels,
                  ArrayRef<SourceLoc> argLabelLocs, bool hasTrailingClosure,
                  ConcreteDeclRef decl, bool implicit, AccessSemantics semantics);
    
  public:
    /// Create a subscript.
    ///
    /// Note: do not create new callers to this entry point; use the entry point
    /// that takes separate index arguments.
    static SubscriptExpr *
    create(ASTContext &ctx, Expr *base, Expr *index,
           ConcreteDeclRef decl = ConcreteDeclRef(), bool implicit = false,
           AccessSemantics semantics = AccessSemantics::Ordinary,
           llvm::function_ref<Type(const Expr *)> getType =
               [](const Expr *E) -> Type { return E->getType(); });
  
    /// Create a new subscript.
    static SubscriptExpr *create(ASTContext &ctx, Expr *base,
                                 SourceLoc lSquareLoc,
                                 ArrayRef<Expr *> indexArgs,
                                 ArrayRef<Identifier> indexArgLabels,
                                 ArrayRef<SourceLoc> indexArgLabelLocs,
                                 SourceLoc rSquareLoc,
                                 Expr *trailingClosure,
                                 ConcreteDeclRef decl = ConcreteDeclRef(),
                                 bool implicit = false,
                                 AccessSemantics semantics
                                   = AccessSemantics::Ordinary);
  
    /// getIndex - Retrieve the index of the subscript expression, i.e., the
    /// "offset" into the base value.
    Expr *getIndex() const { return Index; }
    void setIndex(Expr *E) { Index = E; }
  
    unsigned getNumArguments() const {
      return Bits.SubscriptExpr.NumArgLabels;
    }
  
    bool hasArgumentLabelLocs() const {
      return Bits.SubscriptExpr.HasArgLabelLocs;
    }
  
    /// Whether this call was written with a trailing closure.
    bool hasTrailingClosure() const {
      return Bits.SubscriptExpr.HasTrailingClosure;
    }
  
    /// Determine whether this subscript reference should bypass the
    /// ordinary accessors.
    AccessSemantics getAccessSemantics() const {
      return (AccessSemantics) Bits.SubscriptExpr.Semantics;
    }
    
    SourceLoc getLoc() const { return Index->getStartLoc(); }
    SourceLoc getStartLoc() const { return getBase()->getStartLoc(); }
    SourceLoc getEndLoc() const {
      auto end = Index->getEndLoc();
      return end.isValid() ? end : getBase()->getEndLoc();
    }
    
    static bool classof(const Expr *E) {
      return E->getKind() == ExprKind::Subscript;
    }
  };
  
  /// Subscripting expression that applies a keypath to a base.
  class KeyPathApplicationExpr : public Expr {
    Expr *Base;
    Expr *KeyPath;
    SourceLoc LBracketLoc, RBracketLoc;
    
  public:
    KeyPathApplicationExpr(Expr *base, SourceLoc lBracket, Expr *keyPath,
                           SourceLoc rBracket, Type ty, bool implicit)
      : Expr(ExprKind::KeyPathApplication, implicit, ty),
        Base(base), KeyPath(keyPath), LBracketLoc(lBracket), RBracketLoc(rBracket)
    {}
    
    SourceLoc getLoc() const { return LBracketLoc; }
    SourceLoc getStartLoc() const { return Base->getStartLoc(); }
    SourceLoc getEndLoc() const { return RBracketLoc; }
    
    Expr *getBase() const { return Base; }
    void setBase(Expr *E) { Base = E; }
    Expr *getKeyPath() const { return KeyPath; }
    void setKeyPath(Expr *E) { KeyPath = E; }
    
    static bool classof(const Expr *E) {
      return E->getKind() == ExprKind::KeyPathApplication;
    }
  };
  
  /// A member access (foo.bar) on an expression with unresolved type.
  class UnresolvedDotExpr : public Expr {
    Expr *SubExpr;
    SourceLoc DotLoc;
    DeclNameLoc NameLoc;
    DeclName Name;
    ArrayRef<ValueDecl *> OuterAlternatives;
  
  public:
    UnresolvedDotExpr(
        Expr *subexpr, SourceLoc dotloc, DeclName name, DeclNameLoc nameloc,
        bool Implicit,
        ArrayRef<ValueDecl *> outerAlternatives = ArrayRef<ValueDecl *>())
        : Expr(ExprKind::UnresolvedDot, Implicit), SubExpr(subexpr),
          DotLoc(dotloc), NameLoc(nameloc), Name(name),
          OuterAlternatives(outerAlternatives) {
      Bits.UnresolvedDotExpr.FunctionRefKind =
        static_cast<unsigned>(NameLoc.isCompound() ? FunctionRefKind::Compound
                                                   : FunctionRefKind::Unapplied);
    }
    
    SourceLoc getLoc() const { return NameLoc.getBaseNameLoc(); }
  
    SourceLoc getStartLoc() const {
      return (DotLoc.isInvalid() ? NameLoc.getSourceRange().End 
                                 : SubExpr->getStartLoc());
    }
    SourceLoc getEndLoc() const {
      return NameLoc.getSourceRange().End;
    }
  
    SourceLoc getDotLoc() const { return DotLoc; }
    Expr *getBase() const { return SubExpr; }
    void setBase(Expr *e) { SubExpr = e; }
  
    DeclName getName() const { return Name; }
    DeclNameLoc getNameLoc() const { return NameLoc; }
  
    ArrayRef<ValueDecl *> getOuterAlternatives() const {
      return OuterAlternatives;
    }
  
    /// Retrieve the kind of function reference.
    FunctionRefKind getFunctionRefKind() const {
      return static_cast<FunctionRefKind>(Bits.UnresolvedDotExpr.FunctionRefKind);
    }
  
    /// Set the kind of function reference.
    void setFunctionRefKind(FunctionRefKind refKind) {
      Bits.UnresolvedDotExpr.FunctionRefKind = static_cast<unsigned>(refKind);
    }
  
    static bool classof(const Expr *E) {
      return E->getKind() == ExprKind::UnresolvedDot;
    }
  };
  
  /// TupleElementExpr - Refer to an element of a tuple,
  /// e.g. "(1,field:2).field".
  class TupleElementExpr : public Expr {
    Expr *SubExpr;
    SourceLoc NameLoc;
    SourceLoc DotLoc;
  
  public:
    TupleElementExpr(Expr *SubExpr, SourceLoc DotLoc, unsigned FieldNo,
                     SourceLoc NameLoc, Type Ty)
      : Expr(ExprKind::TupleElement, /*Implicit=*/false, Ty), SubExpr(SubExpr),
        NameLoc(NameLoc), DotLoc(DotLoc) {
      Bits.TupleElementExpr.FieldNo = FieldNo;
    }
  
    SourceLoc getLoc() const { return NameLoc; }
    Expr *getBase() const { return SubExpr; }
    void setBase(Expr *e) { SubExpr = e; }
  
    unsigned getFieldNumber() const { return Bits.TupleElementExpr.FieldNo; }
    SourceLoc getNameLoc() const { return NameLoc; }  
    SourceLoc getDotLoc() const { return DotLoc; }
    
    SourceLoc getStartLoc() const { return getBase()->getStartLoc(); }
    SourceLoc getEndLoc() const { return getNameLoc(); }
  
    static bool classof(const Expr *E) {
      return E->getKind() == ExprKind::TupleElement;
    }
  };
  
  /// Describes a monadic bind from T? to T.
  ///
  /// In a ?-chain expression, this is the part that's spelled with a
  /// postfix ?.
  ///
  /// A BindOptionalExpr must always appear within a
  /// OptionalEvaluationExpr.  If the operand of the BindOptionalExpr
  /// evaluates to a missing value, the OptionalEvaluationExpr
  /// immediately completes and produces a missing value in the result
  /// type.
  ///
  /// The depth of the BindOptionalExpr indicates which
  /// OptionalEvaluationExpr is completed, in case the BindOptionalExpr
  /// is contained within more than one such expression.
  class BindOptionalExpr : public Expr {
    Expr *SubExpr;
    SourceLoc QuestionLoc;
  
  public:
    BindOptionalExpr(Expr *subExpr, SourceLoc questionLoc,
                     unsigned depth, Type ty = Type())
      : Expr(ExprKind::BindOptional, /*Implicit=*/ questionLoc.isInvalid(), ty),
        SubExpr(subExpr), QuestionLoc(questionLoc) {
      Bits.BindOptionalExpr.Depth = depth;
      assert(Bits.BindOptionalExpr.Depth == depth && "bitfield truncation");
    }
  
    SourceRange getSourceRange() const {
      if (QuestionLoc.isInvalid())
        return SubExpr->getSourceRange();
      return SourceRange(SubExpr->getStartLoc(), QuestionLoc);
    }
    SourceLoc getStartLoc() const {
      return SubExpr->getStartLoc();
    }
    SourceLoc getEndLoc() const {
      return (QuestionLoc.isInvalid() ? SubExpr->getEndLoc() : QuestionLoc);
    }
    SourceLoc getLoc() const { 
      if (isImplicit())
        return SubExpr->getLoc();
  
      return getQuestionLoc(); 
    }
    SourceLoc getQuestionLoc() const { return QuestionLoc; }
  
    unsigned getDepth() const { return Bits.BindOptionalExpr.Depth; }
    void setDepth(unsigned depth) {
      Bits.BindOptionalExpr.Depth = depth;
    }
  
    Expr *getSubExpr() const { return SubExpr; }
    void setSubExpr(Expr *expr) { SubExpr = expr; }
  
    static bool classof(const Expr *E) {
      return E->getKind() == ExprKind::BindOptional;
    }
  };
  
  /// Describes the outer limits of an operation containing
  /// monadic binds of T? to T.
  ///
  /// In a ?-chain expression, this is implicitly formed at the outer
  /// limits of the chain.  For example, in (foo?.bar?().baz).fred,
  /// this is nested immediately within the parens.
  ///
  /// This expression will always have optional type.
  class OptionalEvaluationExpr : public Expr {
    Expr *SubExpr;
  
  public:
    OptionalEvaluationExpr(Expr *subExpr, Type ty = Type())
      : Expr(ExprKind::OptionalEvaluation, /*Implicit=*/ true, ty),
        SubExpr(subExpr) {}
  
    SWIFT_FORWARD_SOURCE_LOCS_TO(SubExpr)
  
    Expr *getSubExpr() const { return SubExpr; }
    void setSubExpr(Expr *expr) { SubExpr = expr; }
  
    static bool classof(const Expr *E) {
      return E->getKind() == ExprKind::OptionalEvaluation;
    }
  };
  
  /// An expression that forces an optional to its underlying value.
  ///
  /// \code
  /// func parseInt(s : String) -> Int? { ... }
  ///
  /// var maybeInt = parseInt("5")     // returns an Int?
  /// var forcedInt = parseInt("5")!   // returns an Int; fails on empty optional
  /// \endcode
  ///
  class ForceValueExpr : public Expr {
    Expr *SubExpr;
    SourceLoc ExclaimLoc;
  
  public:
    ForceValueExpr(Expr *subExpr, SourceLoc exclaimLoc, bool forcedIUO = false)
      : Expr(ExprKind::ForceValue, /*Implicit=*/exclaimLoc.isInvalid(), Type()),
        SubExpr(subExpr), ExclaimLoc(exclaimLoc) {
      Bits.ForceValueExpr.ForcedIUO = forcedIUO;
    }
  
    SourceRange getSourceRange() const {
      if (ExclaimLoc.isInvalid())
        return SubExpr->getSourceRange();
  
      return SourceRange(SubExpr->getStartLoc(), ExclaimLoc);
    }
    SourceLoc getStartLoc() const {
      return SubExpr->getStartLoc();
    }
    SourceLoc getEndLoc() const {
      return (isImplicit() ? SubExpr->getEndLoc() : getExclaimLoc());
    }
    SourceLoc getLoc() const {
      if (!isImplicit())
        return getExclaimLoc();
      
      return SubExpr->getLoc();
    }
    SourceLoc getExclaimLoc() const { return ExclaimLoc; }
  
    Expr *getSubExpr() const { return SubExpr; }
    void setSubExpr(Expr *expr) { SubExpr = expr; }
  
    bool isForceOfImplicitlyUnwrappedOptional() const {
      return Bits.ForceValueExpr.ForcedIUO;
    }
  
    static bool classof(const Expr *E) {
      return E->getKind() == ExprKind::ForceValue;
    }
  };
  
  /// An expression that grants temporary escapability to a nonescaping
  /// closure value.
  ///
  /// This expression is formed by the type checker when a call to the
  /// `withoutActuallyEscaping` declaration is made.
  class MakeTemporarilyEscapableExpr : public Expr {
    Expr *NonescapingClosureValue;
    OpaqueValueExpr *EscapingClosureValue;
    Expr *SubExpr;
    SourceLoc NameLoc, LParenLoc, RParenLoc;
    Expr *OriginalExpr;
  
  public:
    MakeTemporarilyEscapableExpr(SourceLoc NameLoc,
                                 SourceLoc LParenLoc,
                                 Expr *NonescapingClosureValue,
                                 Expr *SubExpr,
                                 SourceLoc RParenLoc,
                                 OpaqueValueExpr *OpaqueValueForEscapingClosure,
                                 Expr *OriginalExpr,
                                 bool implicit = false)
      : Expr(ExprKind::MakeTemporarilyEscapable, implicit, Type()),
        NonescapingClosureValue(NonescapingClosureValue),
        EscapingClosureValue(OpaqueValueForEscapingClosure),
        SubExpr(SubExpr),
        NameLoc(NameLoc), LParenLoc(LParenLoc), RParenLoc(RParenLoc),
        OriginalExpr(OriginalExpr)
    {}
    
    SourceLoc getStartLoc() const {
      return NameLoc;
    }
    SourceLoc getEndLoc() const {
      return RParenLoc;
    }
    
    SourceLoc getLoc() const {
      return NameLoc;
    }
    
    /// Retrieve the opaque value representing the escapable copy of the
    /// closure.
    OpaqueValueExpr *getOpaqueValue() const { return EscapingClosureValue; }
    
    /// Retrieve the nonescaping closure expression.
    Expr *getNonescapingClosureValue() const {
      return NonescapingClosureValue;
    }
    void setNonescapingClosureValue(Expr *e) {
      NonescapingClosureValue = e;
    }
    
    /// Retrieve the subexpression that has access to the escapable copy of the
    /// closure.
    Expr *getSubExpr() const {
      return SubExpr;
    }
    void setSubExpr(Expr *e) {
      SubExpr = e;
    }
  
    /// Retrieve the original 'withoutActuallyEscaping(closure) { ... }'
    //  expression.
    Expr *getOriginalExpr() const {
      return OriginalExpr;
    }
  
    static bool classof(const Expr *E) {
      return E->getKind() == ExprKind::MakeTemporarilyEscapable;
    }
  };
  
  /// An expression that opens up a value of protocol or protocol
  /// composition type and gives a name to its dynamic type.
  ///
  /// This expression is implicitly created by the type checker when
  /// calling a method on a protocol. In the future, this may become an
  /// actual operation within the language.
  class OpenExistentialExpr : public Expr {
    Expr *ExistentialValue;
    OpaqueValueExpr *OpaqueValue;
    Expr *SubExpr;
    SourceLoc ExclaimLoc;
  
  public:
    OpenExistentialExpr(Expr *existentialValue,
                        OpaqueValueExpr *opaqueValue,
                        Expr *subExpr,
                        Type subExprTy)
      : Expr(ExprKind::OpenExistential, /*Implicit=*/ true, subExprTy),
        ExistentialValue(existentialValue), OpaqueValue(opaqueValue), 
        SubExpr(subExpr) { }
  
    SWIFT_FORWARD_SOURCE_LOCS_TO(SubExpr)
  
    /// Retrieve the expression that is being evaluated using the
    /// archetype value.
    ///
    /// This subexpression (and no other) may refer to the archetype
    /// type or the opaque value that stores the archetype's value.
    Expr *getSubExpr() const { return SubExpr; }
  
    /// Set the subexpression that is being evaluated.
    void setSubExpr(Expr *expr) { SubExpr = expr; }
  
    /// Retrieve the existential value that is being opened.
    Expr *getExistentialValue() const { return ExistentialValue; }
  
    /// Set the existential val ue that is being opened.
    void setExistentialValue(Expr *expr) { ExistentialValue = expr; }
  
    /// Retrieve the opaque value representing the value (of archetype
    /// type) stored in the existential.
    OpaqueValueExpr *getOpaqueValue() const { return OpaqueValue; }
  
    /// Retrieve the opened archetype, which can only be referenced
    /// within this expression's subexpression.
    OpenedArchetypeType *getOpenedArchetype() const;
  
    static bool classof(const Expr *E) {
      return E->getKind() == ExprKind::OpenExistential;
    }
  };
  
  /// ImplicitConversionExpr - An abstract class for expressions which
  /// implicitly convert the value of an expression in some way.
  class ImplicitConversionExpr : public Expr {
    Expr *SubExpr;
  
  protected:
    ImplicitConversionExpr(ExprKind kind, Expr *subExpr, Type ty)
      : Expr(kind, /*Implicit=*/true, ty), SubExpr(subExpr) {}
  
  public:
    SWIFT_FORWARD_SOURCE_LOCS_TO(SubExpr)
  
    Expr *getSubExpr() const { return SubExpr; }
    void setSubExpr(Expr *e) { SubExpr = e; }
  
    Expr *getSyntacticSubExpr() const {
      if (auto *ICE = dyn_cast<ImplicitConversionExpr>(SubExpr))
        return ICE->getSyntacticSubExpr();
      return SubExpr;
    }
  
    static bool classof(const Expr *E) {
      return E->getKind() >= ExprKind::First_ImplicitConversionExpr &&
             E->getKind() <= ExprKind::Last_ImplicitConversionExpr;
    }
  };
  
  /// The implicit conversion from a class metatype to AnyObject.
  class ClassMetatypeToObjectExpr : public ImplicitConversionExpr {
  public:
    ClassMetatypeToObjectExpr(Expr *subExpr, Type ty)
      : ImplicitConversionExpr(ExprKind::ClassMetatypeToObject, subExpr, ty) {}
    
    static bool classof(const Expr *E) {
      return E->getKind() == ExprKind::ClassMetatypeToObject;
    }
  };
  
  /// The implicit conversion from a class existential metatype to AnyObject.
  class ExistentialMetatypeToObjectExpr : public ImplicitConversionExpr {
  public:
    ExistentialMetatypeToObjectExpr(Expr *subExpr, Type ty)
      : ImplicitConversionExpr(ExprKind::ExistentialMetatypeToObject, subExpr, ty) {}
    
    static bool classof(const Expr *E) {
      return E->getKind() == ExprKind::ExistentialMetatypeToObject;
    }
  };
    
  /// The implicit conversion from a protocol value metatype to ObjC's Protocol
  /// class type.
  class ProtocolMetatypeToObjectExpr : public ImplicitConversionExpr {
  public:
    ProtocolMetatypeToObjectExpr(Expr *subExpr, Type ty)
      : ImplicitConversionExpr(ExprKind::ProtocolMetatypeToObject, subExpr, ty) {}
    
    static bool classof(const Expr *E) {
      return E->getKind() == ExprKind::ProtocolMetatypeToObject;
    }
  };
    
  /// InjectIntoOptionalExpr - The implicit conversion from T to T?.
  class InjectIntoOptionalExpr : public ImplicitConversionExpr {
  public:
    InjectIntoOptionalExpr(Expr *subExpr, Type ty)
      : ImplicitConversionExpr(ExprKind::InjectIntoOptional, subExpr, ty) {}
  
    static bool classof(const Expr *E) {
      return E->getKind() == ExprKind::InjectIntoOptional;
    }
  };
    
  /// Convert the address of an inout property to a pointer.
  class InOutToPointerExpr : public ImplicitConversionExpr {
  public:
    InOutToPointerExpr(Expr *subExpr, Type ty)
        : ImplicitConversionExpr(ExprKind::InOutToPointer, subExpr, ty) {
      Bits.InOutToPointerExpr.IsNonAccessing = false;
    }
  
    /// Is this conversion "non-accessing"?  That is, is it only using the
    /// pointer for its identity, as opposed to actually accessing the memory?
    bool isNonAccessing() const {
      return Bits.InOutToPointerExpr.IsNonAccessing;
    }
    void setNonAccessing(bool nonAccessing = true) {
      Bits.InOutToPointerExpr.IsNonAccessing = nonAccessing;
    }
  
    static bool classof(const Expr *E) {
      return E->getKind() == ExprKind::InOutToPointer;
    }
  };
    
  /// Convert the address of an array to a pointer.
  class ArrayToPointerExpr : public ImplicitConversionExpr {
  public:
    ArrayToPointerExpr(Expr *subExpr, Type ty)
        : ImplicitConversionExpr(ExprKind::ArrayToPointer, subExpr, ty) {
      Bits.ArrayToPointerExpr.IsNonAccessing = false;
    }
    
    /// Is this conversion "non-accessing"?  That is, is it only using the
    /// pointer for its identity, as opposed to actually accessing the memory?
    bool isNonAccessing() const {
      return Bits.ArrayToPointerExpr.IsNonAccessing;
    }
    void setNonAccessing(bool nonAccessing = true) {
      Bits.ArrayToPointerExpr.IsNonAccessing = nonAccessing;
    }
  
    static bool classof(const Expr *E) {
      return E->getKind() == ExprKind::ArrayToPointer;
    }
  };
    
  /// Convert the a string to a pointer referencing its encoded representation.
  class StringToPointerExpr : public ImplicitConversionExpr {
  public:
    StringToPointerExpr(Expr *subExpr, Type ty)
      : ImplicitConversionExpr(ExprKind::StringToPointer, subExpr, ty) {}
    
    static bool classof(const Expr *E) {
      return E->getKind() == ExprKind::StringToPointer;
    }
  };
    
  /// Convert a pointer to a different kind of pointer.
  class PointerToPointerExpr : public ImplicitConversionExpr {
  public:
    PointerToPointerExpr(Expr *subExpr, Type ty)
      : ImplicitConversionExpr(ExprKind::PointerToPointer, subExpr, ty) {}
    
    static bool classof(const Expr *E) {
      return E->getKind() == ExprKind::PointerToPointer;
    }
  };
  
  /// Convert between a foreign object and its corresponding Objective-C object.
  class ForeignObjectConversionExpr : public ImplicitConversionExpr {
  public:
    ForeignObjectConversionExpr(Expr *subExpr, Type ty)
      : ImplicitConversionExpr(ExprKind::ForeignObjectConversion, subExpr, ty) {}
    
    static bool classof(const Expr *E) {
      return E->getKind() == ExprKind::ForeignObjectConversion;
    }
  };
  
  /// Construct an unevaluated instance of the underlying metatype.
  class UnevaluatedInstanceExpr : public ImplicitConversionExpr {
  public:
    UnevaluatedInstanceExpr(Expr *subExpr, Type ty)
      : ImplicitConversionExpr(ExprKind::UnevaluatedInstance, subExpr, ty) {}
  
    static bool classof(const Expr *E) {
      return E->getKind() == ExprKind::UnevaluatedInstance;
    }
  };
  
  /// TupleShuffleExpr - This represents a permutation of a tuple value to a new
  /// tuple type.
  ///
  /// If hasScalarSource() is true, the subexpression should be treated
  /// as if it were implicitly injected into a single-element tuple
  /// type.  Otherwise, the subexpression is known to have a tuple type.
  class TupleShuffleExpr final : public ImplicitConversionExpr,
      private llvm::TrailingObjects<TupleShuffleExpr, Expr *, int, unsigned> {
    friend TrailingObjects;
  
    size_t numTrailingObjects(OverloadToken<Expr *>) const {
      return Bits.TupleShuffleExpr.NumCallerDefaultArgs;
    }
    size_t numTrailingObjects(OverloadToken<int>) const {
      return Bits.TupleShuffleExpr.NumElementMappings;
    }
    size_t numTrailingObjects(OverloadToken<unsigned>) const {
      return Bits.TupleShuffleExpr.NumVariadicArgs;
    }
  
  public:
    enum : int {
      /// The element mapping value indicating that a field of the destination
      /// tuple should be default-initialized.
      DefaultInitialize = -1,
      /// The element mapping is part of the variadic field.
      Variadic = -2,
      /// The element mapping value indicating that the field of the
      /// destination tuple should be default-initialized with an expression
      /// provided by the caller.
      /// FIXME: Yet another indication that TupleShuffleExpr uses the wrong
      /// formulation.
      CallerDefaultInitialize = -3
    };
  
    enum TypeImpact {
      /// The source value is a tuple which is destructured and modified to
      /// create the result, which is a tuple.
      TupleToTuple,
  
      /// The source value is a tuple which is destructured and modified to
      /// create the result, which is a scalar because it has one element and
      /// no labels.
      TupleToScalar,
  
      /// The source value is an individual value (possibly one with tuple
      /// type) which is inserted into a particular position in the result,
      /// which is a tuple.
      ScalarToTuple
  
      // (TupleShuffleExprs are never created for a scalar-to-scalar conversion.)
    };
  
  private:
    /// If we're doing a varargs shuffle, this is the array type to build.
    Type VarargsArrayTy;
  
    /// If there are any default arguments, the owning function
    /// declaration.
    ConcreteDeclRef DefaultArgsOwner;
  
    TupleShuffleExpr(Expr *subExpr, ArrayRef<int> elementMapping,
                     TypeImpact typeImpact,
                     ConcreteDeclRef defaultArgsOwner,
                     ArrayRef<unsigned> VariadicArgs,
                     Type VarargsArrayTy,
                     ArrayRef<Expr *> CallerDefaultArgs,
                     Type ty)
      : ImplicitConversionExpr(ExprKind::TupleShuffle, subExpr, ty),
        VarargsArrayTy(VarargsArrayTy), DefaultArgsOwner(defaultArgsOwner) {
      Bits.TupleShuffleExpr.TypeImpact = typeImpact;
      Bits.TupleShuffleExpr.NumCallerDefaultArgs = CallerDefaultArgs.size();
      Bits.TupleShuffleExpr.NumElementMappings = elementMapping.size();
      Bits.TupleShuffleExpr.NumVariadicArgs = VariadicArgs.size();
      std::uninitialized_copy(CallerDefaultArgs.begin(), CallerDefaultArgs.end(),
                              getTrailingObjects<Expr*>());
      std::uninitialized_copy(elementMapping.begin(), elementMapping.end(),
                              getTrailingObjects<int>());
      std::uninitialized_copy(VariadicArgs.begin(), VariadicArgs.end(),
                              getTrailingObjects<unsigned>());
    }
  
  public:
    static TupleShuffleExpr *create(ASTContext &ctx, Expr *subExpr,
                                    ArrayRef<int> elementMapping,
                                    TypeImpact typeImpact,
                                    ConcreteDeclRef defaultArgsOwner,
                                    ArrayRef<unsigned> VariadicArgs,
                                    Type VarargsArrayTy,
                                    ArrayRef<Expr *> CallerDefaultArgs,
                                    Type ty);
  
    ArrayRef<int> getElementMapping() const {
      return {getTrailingObjects<int>(),
              static_cast<size_t>(Bits.TupleShuffleExpr.NumElementMappings)};
    }
  
    /// What is the type impact of this shuffle?
    TypeImpact getTypeImpact() const {
      return TypeImpact(Bits.TupleShuffleExpr.TypeImpact);
    }
  
    bool isSourceScalar() const {
      return getTypeImpact() == ScalarToTuple;
    }
  
    bool isResultScalar() const {
      return getTypeImpact() == TupleToScalar;
    }
  
    Type getVarargsArrayType() const {
      assert(!VarargsArrayTy.isNull());
      return VarargsArrayTy;
    }
    Type getVarargsArrayTypeOrNull() const {
      return VarargsArrayTy;
    }
  
    /// Retrieve the argument indices for the variadic arguments.
    ArrayRef<unsigned> getVariadicArgs() const {
      return {getTrailingObjects<unsigned>(),
              static_cast<size_t>(Bits.TupleShuffleExpr.NumVariadicArgs)};
    }
  
    /// Retrieve the owner of the default arguments.
    ConcreteDeclRef getDefaultArgsOwner() const { return DefaultArgsOwner; }
  
    /// Retrieve the caller-defaulted arguments.
    ArrayRef<Expr *> getCallerDefaultArgs() const {
      return {getTrailingObjects<Expr*>(),
              static_cast<size_t>(Bits.TupleShuffleExpr.NumCallerDefaultArgs)};
    }
  
    /// Retrieve the caller-defaulted arguments.
    MutableArrayRef<Expr *> getCallerDefaultArgs() {
      return {getTrailingObjects<Expr*>(),
              static_cast<size_t>(Bits.TupleShuffleExpr.NumCallerDefaultArgs)};
    }
  
    static bool classof(const Expr *E) {
      return E->getKind() == ExprKind::TupleShuffle;
    }
  };
  
  /// LoadExpr - Turn an l-value into an r-value by performing a "load"
  /// operation.  This operation may actually be a logical operation,
  /// i.e. one implemented using a call to a potentially user-defined
  /// function instead of a simple memory transaction.
  class LoadExpr : public ImplicitConversionExpr {
  public:
    LoadExpr(Expr *subExpr, Type type)
      : ImplicitConversionExpr(ExprKind::Load, subExpr, type) {}
  
    static bool classof(const Expr *E) { return E->getKind() == ExprKind::Load; }
  };
  
  /// This is a conversion from an expression of UnresolvedType to an arbitrary
  /// other type, and from an arbitrary type to UnresolvedType.  This node does
  /// not appear in valid code, only in code involving diagnostics.
  class UnresolvedTypeConversionExpr : public ImplicitConversionExpr {
  public:
    UnresolvedTypeConversionExpr(Expr *subExpr, Type type)
    : ImplicitConversionExpr(ExprKind::UnresolvedTypeConversion, subExpr, type) {}
  
    static bool classof(const Expr *E) {
      return E->getKind() == ExprKind::UnresolvedTypeConversion;
    }
  };
  
  /// FunctionConversionExpr - Convert a function to another function type,
  /// which might involve renaming the parameters or handling substitutions
  /// of subtypes (in the return) or supertypes (in the input).
  ///
  /// FIXME: This should be a CapturingExpr.
  class FunctionConversionExpr : public ImplicitConversionExpr {
  public:
    FunctionConversionExpr(Expr *subExpr, Type type)
      : ImplicitConversionExpr(ExprKind::FunctionConversion, subExpr, type) {}
    
    static bool classof(const Expr *E) {
      return E->getKind() == ExprKind::FunctionConversion;
    }
  };
  
  /// Perform a function conversion from one function that to one that has a
  /// covariant result type.
  ///
  /// This conversion is technically unsafe; however, semantic analysis will
  /// only introduce such a conversion in cases where other language features
  /// (i.e., Self returns) enforce static safety. Additionally, this conversion
  /// avoids changing the ABI of the function in question.
  class CovariantFunctionConversionExpr : public ImplicitConversionExpr {
  public:
    CovariantFunctionConversionExpr(Expr *subExpr, Type type)
      : ImplicitConversionExpr(ExprKind::CovariantFunctionConversion, subExpr,
                               type) { }
  
    static bool classof(const Expr *E) {
      return E->getKind() == ExprKind::CovariantFunctionConversion;
    }
  };
  
  /// Perform a conversion from a superclass to a subclass for a call to
  /// a method with a covariant result type.
  ///
  /// This conversion is technically unsafe; however, semantic analysis will
  /// only introduce such a conversion in cases where other language features
  /// (i.e., Self returns) enforce static safety.
  class CovariantReturnConversionExpr : public ImplicitConversionExpr {
  public:
    CovariantReturnConversionExpr(Expr *subExpr, Type type)
      : ImplicitConversionExpr(ExprKind::CovariantReturnConversion, subExpr,
                               type) { }
  
    static bool classof(const Expr *E) {
      return E->getKind() == ExprKind::CovariantReturnConversion;
    }
  };
  
  /// Perform a function conversion from a function returning an
  /// Optional<T> to a function returning T.
  ///
  /// This is generated during expression type checking in places where
  /// we need to force the result type of a function being called. When
  /// we go to rewrite the call, we remove this node and force the
  /// result of the call to the underlying function. It should never
  /// exist outside of this final stage of expression type checking.
  class ImplicitlyUnwrappedFunctionConversionExpr
      : public ImplicitConversionExpr {
  public:
    ImplicitlyUnwrappedFunctionConversionExpr(Expr *subExpr, Type type)
        : ImplicitConversionExpr(ExprKind::ImplicitlyUnwrappedFunctionConversion,
                                 subExpr, type) {}
  
    static bool classof(const Expr *E) {
      return E->getKind() == ExprKind::ImplicitlyUnwrappedFunctionConversion;
    }
  };
  
  /// MetatypeConversionExpr - Convert a metatype to another metatype
  /// using essentially a derived-to-base conversion.
  class MetatypeConversionExpr : public ImplicitConversionExpr {
  public:
    MetatypeConversionExpr(Expr *subExpr, Type type)
      : ImplicitConversionExpr(ExprKind::MetatypeConversion, subExpr, type) {}
    
    static bool classof(const Expr *E) {
      return E->getKind() == ExprKind::MetatypeConversion;
    }
  };
    
  /// CollectionUpcastConversionExpr - Convert a collection whose
  /// elements have some type T to the same kind of collection whose
  /// elements have type U, where U is a subtype of T.
  class CollectionUpcastConversionExpr : public ImplicitConversionExpr {
  public:
    struct ConversionPair {
      OpaqueValueExpr *OrigValue;
      Expr *Conversion;
  
      explicit operator bool() const { return OrigValue != nullptr; }
    };
  private:
    ConversionPair KeyConversion;
    ConversionPair ValueConversion;
  public:
    CollectionUpcastConversionExpr(Expr *subExpr, Type type,
                                   ConversionPair keyConversion,
                                   ConversionPair valueConversion)
      : ImplicitConversionExpr(
          ExprKind::CollectionUpcastConversion, subExpr, type),
        KeyConversion(keyConversion), ValueConversion(valueConversion) {
      assert((!KeyConversion || ValueConversion)
             && "key conversion without value conversion");
    }
  
    /// Returns the expression that should be used to perform a
    /// conversion of the collection's values; null if the conversion
    /// is formally trivial because the key type does not change.
    const ConversionPair &getKeyConversion() const {
      return KeyConversion;
    }
    void setKeyConversion(const ConversionPair &pair) {
      KeyConversion = pair;
    }
  
    /// Returns the expression that should be used to perform a
    /// conversion of the collection's values; null if the conversion
    /// is formally trivial because the value type does not change.
    const ConversionPair &getValueConversion() const {
      return ValueConversion;
    }
    void setValueConversion(const ConversionPair &pair) {
      ValueConversion = pair;
    }
  
    static bool classof(const Expr *E) {
      return E->getKind() == ExprKind::CollectionUpcastConversion;
    }
  };
    
  /// ErasureExpr - Perform type erasure by converting a value to existential
  /// type. For example:
  ///
  /// \code
  /// protocol Printable {}
  /// struct Book {}
  ///
  /// var printable: Printable = Book() // erases type
  /// var printableType: Printable.Type = Book.self // erases metatype
  /// \endcode
  ///
  /// The type of the expression should always satisfy isAnyExistentialType().
  ///
  /// The type of the sub-expression should always be either:
  ///   - a non-existential type of the appropriate kind or
  ///   - an existential type of the appropriate kind which is a subtype
  ///     of the result type.
  ///
  /// "Appropriate kind" means e.g. a concrete/existential metatype if the
  /// result is an existential metatype.
  class ErasureExpr final : public ImplicitConversionExpr,
      private llvm::TrailingObjects<ErasureExpr, ProtocolConformanceRef> {
    friend TrailingObjects;
  
    ErasureExpr(Expr *subExpr, Type type,
                ArrayRef<ProtocolConformanceRef> conformances)
      : ImplicitConversionExpr(ExprKind::Erasure, subExpr, type) {
      Bits.ErasureExpr.NumConformances = conformances.size();
      std::uninitialized_copy(conformances.begin(), conformances.end(),
                              getTrailingObjects<ProtocolConformanceRef>());
    }
  
  public:
    static ErasureExpr *create(ASTContext &ctx, Expr *subExpr, Type type,
                               ArrayRef<ProtocolConformanceRef> conformances);
  
    /// Retrieve the mapping specifying how the type of the subexpression
    /// maps to the resulting existential type. If the resulting existential
    /// type involves several different protocols, there will be mappings for each
    /// of those protocols, in the order in which the existential type expands
    /// its properties.
    ///
    /// The entries in this array may be null, indicating that the conformance
    /// to the corresponding protocol is trivial (because the source
    /// type is either an archetype or an existential type that conforms to
    /// that corresponding protocol).
    ArrayRef<ProtocolConformanceRef> getConformances() const {
      return {getTrailingObjects<ProtocolConformanceRef>(),
              Bits.ErasureExpr.NumConformances };
    }
  
    static bool classof(const Expr *E) {
      return E->getKind() == ExprKind::Erasure;
    }
  };
  
  /// AnyHashableErasureExpr - Perform type erasure by converting a value
  /// to AnyHashable type.
  ///
  /// The type of the sub-expression should always be a type that implements
  /// the Hashable protocol.
  class AnyHashableErasureExpr : public ImplicitConversionExpr {
    ProtocolConformanceRef Conformance;
  
  public:
    AnyHashableErasureExpr(Expr *subExpr, Type type,
                           ProtocolConformanceRef conformance)
      : ImplicitConversionExpr(ExprKind::AnyHashableErasure, subExpr, type),
        Conformance(conformance) {}
  
    /// Retrieve the mapping specifying how the type of the
    /// subexpression conforms to the Hashable protocol.
    ProtocolConformanceRef getConformance() const {
      return Conformance;
    }
    
    static bool classof(const Expr *E) {
      return E->getKind() == ExprKind::AnyHashableErasure;
    }
  };
  
  /// ConditionalBridgeFromObjCExpr - Bridge a value from a non-native
  /// representation.
  class ConditionalBridgeFromObjCExpr : public ImplicitConversionExpr {
    ConcreteDeclRef Conversion;
  
  public:
    ConditionalBridgeFromObjCExpr(Expr *subExpr, Type type,
                                  ConcreteDeclRef conversion)
      : ImplicitConversionExpr(ExprKind::ConditionalBridgeFromObjC, subExpr, type),
        Conversion(conversion) {
    }
  
    /// Retrieve the conversion function.
    ConcreteDeclRef getConversion() const {
      return Conversion;
    }
  
    static bool classof(const Expr *E) {
      return E->getKind() == ExprKind::ConditionalBridgeFromObjC;
    }
  };
  
  /// BridgeFromObjCExpr - Bridge a value from a non-native representation.
  class BridgeFromObjCExpr : public ImplicitConversionExpr {
  public:
    BridgeFromObjCExpr(Expr *subExpr, Type type)
      : ImplicitConversionExpr(ExprKind::BridgeFromObjC, subExpr, type) {}
  
    static bool classof(const Expr *E) {
      return E->getKind() == ExprKind::BridgeFromObjC;
    }
  };
  
  /// BridgeToObjCExpr - Bridge a value to a non-native representation.
  class BridgeToObjCExpr : public ImplicitConversionExpr {
  public:
    BridgeToObjCExpr(Expr *subExpr, Type type)
      : ImplicitConversionExpr(ExprKind::BridgeToObjC, subExpr, type) {}
  
    static bool classof(const Expr *E) {
      return E->getKind() == ExprKind::BridgeToObjC;
    }
  };
  
  /// UnresolvedSpecializeExpr - Represents an explicit specialization using
  /// a type parameter list (e.g. "Vector<Int>") that has not been resolved.
  class UnresolvedSpecializeExpr final : public Expr,
      private llvm::TrailingObjects<UnresolvedSpecializeExpr, TypeLoc> {
    friend TrailingObjects;
  
    Expr *SubExpr;
    SourceLoc LAngleLoc;
    SourceLoc RAngleLoc;
  
    UnresolvedSpecializeExpr(Expr *SubExpr,
                             SourceLoc LAngleLoc,
                             ArrayRef<TypeLoc> UnresolvedParams,
                             SourceLoc RAngleLoc)
      : Expr(ExprKind::UnresolvedSpecialize, /*Implicit=*/false),
        SubExpr(SubExpr), LAngleLoc(LAngleLoc), RAngleLoc(RAngleLoc) {
      Bits.UnresolvedSpecializeExpr.NumUnresolvedParams = UnresolvedParams.size();
      std::uninitialized_copy(UnresolvedParams.begin(), UnresolvedParams.end(),
                              getTrailingObjects<TypeLoc>());
    }
  
  public:
    static UnresolvedSpecializeExpr *
    create(ASTContext &ctx, Expr *SubExpr, SourceLoc LAngleLoc,
           ArrayRef<TypeLoc> UnresolvedParams, SourceLoc RAngleLoc);
    
    Expr *getSubExpr() const { return SubExpr; }
    void setSubExpr(Expr *e) { SubExpr = e; }
    
    /// Retrieve the list of type parameters. These parameters have not yet
    /// been bound to archetypes of the entity to be specialized.
    ArrayRef<TypeLoc> getUnresolvedParams() const {
      return {getTrailingObjects<TypeLoc>(),
              Bits.UnresolvedSpecializeExpr.NumUnresolvedParams};
    }
    MutableArrayRef<TypeLoc> getUnresolvedParams() {
      return {getTrailingObjects<TypeLoc>(),
              Bits.UnresolvedSpecializeExpr.NumUnresolvedParams};
    }
    
    SourceLoc getLoc() const { return LAngleLoc; }
    SourceLoc getLAngleLoc() const { return LAngleLoc; }
    SourceLoc getRAngleLoc() const { return RAngleLoc; }
  
    SourceLoc getStartLoc() const { return SubExpr->getStartLoc(); }
    SourceLoc getEndLoc() const { return RAngleLoc; }
    
    static bool classof(const Expr *E) {
      return E->getKind() == ExprKind::UnresolvedSpecialize;
    }
  };
  
  /// Describes an implicit conversion from a subclass to one of its
  /// superclasses.
  class DerivedToBaseExpr : public ImplicitConversionExpr {
  public:
    DerivedToBaseExpr(Expr *subExpr, Type type)
      : ImplicitConversionExpr(ExprKind::DerivedToBase, subExpr, type) {}
  
    static bool classof(const Expr *E) {
      return E->getKind() == ExprKind::DerivedToBase;
    }
  };
  
  /// Describes an implicit conversion from a value of archetype type to
  /// its concrete superclass.
  class ArchetypeToSuperExpr : public ImplicitConversionExpr {
  public:
    ArchetypeToSuperExpr(Expr *subExpr, Type type)
      : ImplicitConversionExpr(ExprKind::ArchetypeToSuper, subExpr, type) {}
  
    static bool classof(const Expr *E) {
      return E->getKind() == ExprKind::ArchetypeToSuper;
    }
  };
  
  /// The builtin unary '&' operator, which converts the
  /// given lvalue into an 'inout' argument value.
  class InOutExpr : public Expr {
    Expr *SubExpr;
    SourceLoc OperLoc;
  
  public:
    InOutExpr(SourceLoc operLoc, Expr *subExpr, Type baseType,
              bool isImplicit = false);
  
    SourceLoc getStartLoc() const { return OperLoc; }
    SourceLoc getEndLoc() const { return SubExpr->getEndLoc(); }
    SourceLoc getLoc() const { return OperLoc; }
  
    Expr *getSubExpr() const { return SubExpr; }
    void setSubExpr(Expr *e) { SubExpr = e; }
  
    static bool classof(const Expr *E) {
      return E->getKind() == ExprKind::InOut;
    }
  };
  
  /// The not-yet-actually-surfaced '...' varargs expansion operator,
  /// which splices an array into a sequence of variadic arguments.
  class VarargExpansionExpr : public Expr {
    Expr *SubExpr;
  
  public:
    VarargExpansionExpr(Expr *subExpr, bool implicit, Type type = Type())
      : Expr(ExprKind::VarargExpansion, implicit, type), SubExpr(subExpr) {}
  
    SWIFT_FORWARD_SOURCE_LOCS_TO(SubExpr)
  
    Expr *getSubExpr() const { return SubExpr; }
    void setSubExpr(Expr *subExpr) { SubExpr = subExpr; }
  
    static bool classof(const Expr *E) {
      return E->getKind() == ExprKind::VarargExpansion;
    }
  };
  
  /// SequenceExpr - A list of binary operations which has not yet been
  /// folded into a tree.  The operands all have even indices, while the
  /// subexpressions with odd indices are all (potentially overloaded)
  /// references to binary operators.
  class SequenceExpr final : public Expr,
      private llvm::TrailingObjects<SequenceExpr, Expr *> {
    friend TrailingObjects;
  
    SequenceExpr(ArrayRef<Expr*> elements)
      : Expr(ExprKind::Sequence, /*Implicit=*/false) {
      Bits.SequenceExpr.NumElements = elements.size();
      assert(Bits.SequenceExpr.NumElements > 0 && "zero-length sequence!");
      std::uninitialized_copy(elements.begin(), elements.end(),
                              getTrailingObjects<Expr*>());
    }
  
  public:
    static SequenceExpr *create(ASTContext &ctx, ArrayRef<Expr*> elements);
  
    SourceLoc getStartLoc() const {
      return getElement(0)->getStartLoc();
    }
    SourceLoc getEndLoc() const {
      return getElement(getNumElements() - 1)->getEndLoc();
    }
    
    unsigned getNumElements() const { return Bits.SequenceExpr.NumElements; }
  
    MutableArrayRef<Expr*> getElements() {
      return {getTrailingObjects<Expr*>(), Bits.SequenceExpr.NumElements};
    }
  
    ArrayRef<Expr*> getElements() const {
      return {getTrailingObjects<Expr*>(), Bits.SequenceExpr.NumElements};
    }
  
    Expr *getElement(unsigned i) const {
      return getElements()[i];
    }
    void setElement(unsigned i, Expr *e) {
      getElements()[i] = e;
    }
  
    // Implement isa/cast/dyncast/etc.
    static bool classof(const Expr *E) {
      return E->getKind() == ExprKind::Sequence;
    }
  };
  
  
  /// A base class for closure expressions.
  class AbstractClosureExpr : public DeclContext, public Expr {
    CaptureInfo Captures;
  
    /// The set of parameters.
    ParameterList *parameterList;
  
  public:
    AbstractClosureExpr(ExprKind Kind, Type FnType, bool Implicit,
                        unsigned Discriminator, DeclContext *Parent)
        : DeclContext(DeclContextKind::AbstractClosureExpr, Parent),
          Expr(Kind, Implicit, FnType),
          parameterList(nullptr) {
      Bits.AbstractClosureExpr.Discriminator = Discriminator;
    }
  
    CaptureInfo &getCaptureInfo() { return Captures; }
    const CaptureInfo &getCaptureInfo() const { return Captures; }
  
    /// Retrieve the parameters of this closure.
    ParameterList *getParameters() { return parameterList; }
    const ParameterList *getParameters() const { return parameterList; }
    void setParameterList(ParameterList *P);
  
    // Expose this to users.
    using DeclContext::setParent;
  
    /// Returns a discriminator which determines this expression's index
    /// in the sequence of closure expressions within the current
    /// function.
    ///
    /// There are separate sequences for explicit and implicit closures.
    /// This allows explicit closures to maintain a stable numbering
    /// across simple edits that introduce auto closures above them,
    /// which is the best we can reasonably do.
    ///
    /// (Autoclosures are likely to be eliminated immediately, even in
    /// unoptimized builds, so their names are fairly unimportant.  It's
    /// much more likely that explicit closures will survive
    /// optimization and therefore make it into e.g. stack traces.
    /// Having their symbol names be stable across minor code changes is
    /// therefore pretty useful for debugging.)
    unsigned getDiscriminator() const {
      return Bits.AbstractClosureExpr.Discriminator;
    }
    void setDiscriminator(unsigned discriminator) {
      assert(getDiscriminator() == InvalidDiscriminator);
      assert(discriminator != InvalidDiscriminator);
      Bits.AbstractClosureExpr.Discriminator = discriminator;
    }
    enum : unsigned { InvalidDiscriminator = 0xFFFF };
  
    /// Retrieve the result type of this closure.
    Type getResultType(llvm::function_ref<Type(const Expr *)> getType =
                           [](const Expr *E) -> Type {
      return E->getType();
    }) const;
  
    /// Return whether this closure is throwing when fully applied.
    bool isBodyThrowing() const;
  
    /// Whether this closure consists of a single expression.
    bool hasSingleExpressionBody() const;
  
    static bool classof(const Expr *E) {
      return E->getKind() >= ExprKind::First_AbstractClosureExpr &&
             E->getKind() <= ExprKind::Last_AbstractClosureExpr;
    }
  
    static bool classof(const DeclContext *DC) {
      return DC->getContextKind() == DeclContextKind::AbstractClosureExpr;
    }
  
    using DeclContext::operator new;
    using Expr::dump;
  };
  
  /// SerializedAbstractClosureExpr - This represents what was originally an
  /// AbstractClosureExpr during serialization. It is preserved only to maintain
  /// the correct AST structure and remangling after deserialization.
  class SerializedAbstractClosureExpr : public SerializedLocalDeclContext {
    const Type Ty;
    llvm::PointerIntPair<Type, 1> TypeAndImplicit;
    const unsigned Discriminator;
  
  public:
    SerializedAbstractClosureExpr(Type Ty, bool Implicit, unsigned Discriminator,
                                  DeclContext *Parent)
      : SerializedLocalDeclContext(LocalDeclContextKind::AbstractClosure,
                                   Parent),
        TypeAndImplicit(llvm::PointerIntPair<Type, 1>(Ty, Implicit)),
        Discriminator(Discriminator) {}
  
    Type getType() const {
      return TypeAndImplicit.getPointer();
    }
  
    unsigned getDiscriminator() const {
      return Discriminator;
    }
  
    bool isImplicit() const {
      return TypeAndImplicit.getInt();
    }
  
    static bool classof(const DeclContext *DC) {
      if (auto LDC = dyn_cast<SerializedLocalDeclContext>(DC))
        return LDC->getLocalDeclContextKind() ==
          LocalDeclContextKind::AbstractClosure;
      return false;
    }
  };
  
  /// An explicit unnamed function expression, which can optionally have
  /// named arguments.
  ///
  /// \code
  ///     { $0 + $1 }
  ///     { a, b -> Int in a + b }
  ///     { (a : Int, b : Int) -> Int in a + b }
  ///     { [weak c] (a : Int) -> Int in a + c!.getFoo() }
  /// \endcode
  class ClosureExpr : public AbstractClosureExpr {
  
    /// The location of the "throws", if present.
    SourceLoc ThrowsLoc;
    
    /// The location of the '->' denoting an explicit return type,
    /// if present.
    SourceLoc ArrowLoc;
  
    /// The location of the "in", if present.
    SourceLoc InLoc;
  
    /// The explicitly-specified result type.
    TypeLoc ExplicitResultType;
  
    /// The body of the closure, along with a bit indicating whether it
    /// was originally just a single expression.
    llvm::PointerIntPair<BraceStmt *, 1, bool> Body;
    
  public:
    ClosureExpr(ParameterList *params, SourceLoc throwsLoc, SourceLoc arrowLoc,
                SourceLoc inLoc, TypeLoc explicitResultType,
                unsigned discriminator, DeclContext *parent)
      : AbstractClosureExpr(ExprKind::Closure, Type(), /*Implicit=*/false,
                            discriminator, parent),
        ThrowsLoc(throwsLoc), ArrowLoc(arrowLoc), InLoc(inLoc),
        ExplicitResultType(explicitResultType),
        Body(nullptr) {
      setParameterList(params);
      Bits.ClosureExpr.HasAnonymousClosureVars = false;
    }
  
    SourceRange getSourceRange() const;
    SourceLoc getStartLoc() const;
    SourceLoc getEndLoc() const;
    SourceLoc getLoc() const;
  
    BraceStmt *getBody() const { return Body.getPointer(); }
    void setBody(BraceStmt *S, bool isSingleExpression) {
      Body.setPointer(S);
      Body.setInt(isSingleExpression);
    }
  
    /// Determine whether the parameters of this closure are actually
    /// anonymous closure variables.
    bool hasAnonymousClosureVars() const {
      return Bits.ClosureExpr.HasAnonymousClosureVars;
    }
  
    /// Set the parameters of this closure along with a flag indicating
    /// whether these parameters are actually anonymous closure variables.
    void setHasAnonymousClosureVars() {
      Bits.ClosureExpr.HasAnonymousClosureVars = true;
    }
    
    /// Determine whether this closure expression has an
    /// explicitly-specified result type.
    bool hasExplicitResultType() const { return ArrowLoc.isValid(); }
  
    
    /// Retrieve the location of the \c '->' for closures with an
    /// explicit result type.
    SourceLoc getArrowLoc() const {
      assert(hasExplicitResultType() && "No arrow location");
      return ArrowLoc;
    }
  
    /// Retrieve the location of the \c in for a closure that has it.
    SourceLoc getInLoc() const {
      return InLoc;
    }
    
    /// Retrieve the location of the 'throws' for a closure that has it.
    SourceLoc getThrowsLoc() const {
      return ThrowsLoc;
    }
  
    /// Retrieve the explicit result type location information.
    TypeLoc &getExplicitResultTypeLoc() {
      assert(hasExplicitResultType() && "No explicit result type");
      return ExplicitResultType;
    }
    
    void setExplicitResultType(SourceLoc arrowLoc, TypeLoc resultType) {
      ArrowLoc = arrowLoc;
      ExplicitResultType = resultType;
    }
  
    /// Determine whether the closure has a single expression for its
    /// body.
    ///
    /// This will be true for closures such as, e.g.,
    /// \code
    ///   { $0 + 1 }
    /// \endcode
    ///
    /// or
    ///
    /// \code
    ///   { x, y in x > y }
    /// \endcode
    ///
    /// ... even if the closure has been coerced to return Void by the type
    /// checker. This function does not return true for empty closures.
    bool hasSingleExpressionBody() const {
      return Body.getInt();
    }
  
    /// Retrieve the body for closure that has a single expression for
    /// its body.
    ///
    /// Only valid when \c hasSingleExpressionBody() is true.
    Expr *getSingleExpressionBody() const;
  
    /// Set the body for a closure that has a single expression as its
    /// body.
    ///
    /// This routine cannot change whether a closure has a single expression as
    /// its body; it can only update that expression.
    void setSingleExpressionBody(Expr *NewBody);
  
    /// Is this a completely empty closure?
    bool hasEmptyBody() const;
  
    static bool classof(const Expr *E) {
      return E->getKind() == ExprKind::Closure;
    }
    static bool classof(const AbstractClosureExpr *E) {
      return E->getKind() == ExprKind::Closure;
    }
    static bool classof(const DeclContext *C) {
      return isa<AbstractClosureExpr>(C) && classof(cast<AbstractClosureExpr>(C));
    }
  };
  
  
  /// This is a closure of the contained subexpression that is formed
  /// when a scalar expression is converted to @autoclosure function type.
  /// For example:
  /// \code
  ///   func f(x : @autoclosure () -> Int)
  ///   f(42)  // AutoclosureExpr convert from Int to ()->Int
  /// \endcode
  class AutoClosureExpr : public AbstractClosureExpr {
    BraceStmt *Body;
  
  public:
    AutoClosureExpr(Expr *Body, Type ResultTy, unsigned Discriminator,
                    DeclContext *Parent)
        : AbstractClosureExpr(ExprKind::AutoClosure, ResultTy, /*Implicit=*/true,
                              Discriminator, Parent) {
      setBody(Body);
    }
  
    SourceRange getSourceRange() const;
    SourceLoc getStartLoc() const;
    SourceLoc getEndLoc() const;
    SourceLoc getLoc() const;
  
    BraceStmt *getBody() const { return Body; }
    void setBody(Expr *E);
  
    // Expose this to users.
    using DeclContext::setParent;
  
    /// Returns the body of the autoclosure as an \c Expr.
    ///
    /// The body of an autoclosure always consists of a single expression.
    Expr *getSingleExpressionBody() const;
  
    // Implement isa/cast/dyncast/etc.
    static bool classof(const Expr *E) {
      return E->getKind() == ExprKind::AutoClosure;
    }
    static bool classof(const AbstractClosureExpr *E) {
      return E->getKind() == ExprKind::AutoClosure;
    }
    static bool classof(const DeclContext *C) {
      return isa<AbstractClosureExpr>(C) && classof(cast<AbstractClosureExpr>(C));
    }
  };
  
  /// Instances of this structure represent elements of the capture list that can
  /// optionally occur in a capture expression.
  struct CaptureListEntry {
    VarDecl *Var;
    PatternBindingDecl *Init;
  
    CaptureListEntry(VarDecl *Var, PatternBindingDecl *Init)
    : Var(Var), Init(Init) {
    }
  };
  
  /// CaptureListExpr - This expression represents the capture list on an explicit
  /// closure.  Because the capture list is evaluated outside of the closure, this
  /// CaptureList wraps the ClosureExpr.  The dynamic semantics are that evaluates
  /// the variable bindings from the capture list, then evaluates the
  /// subexpression (the closure itself) and returns the result.
  class CaptureListExpr final : public Expr,
      private llvm::TrailingObjects<CaptureListExpr, CaptureListEntry> {
    friend TrailingObjects;
  
    ClosureExpr *closureBody;
  
    CaptureListExpr(ArrayRef<CaptureListEntry> captureList,
                    ClosureExpr *closureBody)
      : Expr(ExprKind::CaptureList, /*Implicit=*/false, Type()),
        closureBody(closureBody) {
      Bits.CaptureListExpr.NumCaptures = captureList.size();
      std::uninitialized_copy(captureList.begin(), captureList.end(),
                              getTrailingObjects<CaptureListEntry>());
    }
  
  public:
    static CaptureListExpr *create(ASTContext &ctx,
                                   ArrayRef<CaptureListEntry> captureList,
                                   ClosureExpr *closureBody);
  
    ArrayRef<CaptureListEntry> getCaptureList() {
      return {getTrailingObjects<CaptureListEntry>(),
              Bits.CaptureListExpr.NumCaptures};
    }
    ClosureExpr *getClosureBody() { return closureBody; }
    const ClosureExpr *getClosureBody() const { return closureBody; }
  
    void setClosureBody(ClosureExpr *body) { closureBody = body; }
  
    /// This is a bit weird, but the capture list is lexically contained within
    /// the closure, so the ClosureExpr has the full source range.
    SWIFT_FORWARD_SOURCE_LOCS_TO(closureBody)
  
    // Implement isa/cast/dyncast/etc.
    static bool classof(const Expr *E) {
      return E->getKind() == ExprKind::CaptureList;
    }
  };
  
  /// DynamicTypeExpr - "type(of: base)" - Produces a metatype value.
  ///
  /// The metatype value comes from evaluating an expression then retrieving the
  /// metatype of the result.
  class DynamicTypeExpr : public Expr {
    SourceLoc KeywordLoc;
    SourceLoc LParenLoc;
    Expr *Base;
    SourceLoc RParenLoc;
  
  public:
    explicit DynamicTypeExpr(SourceLoc KeywordLoc, SourceLoc LParenLoc,
                             Expr *Base, SourceLoc RParenLoc, Type Ty)
      : Expr(ExprKind::DynamicType, /*Implicit=*/false, Ty),
        KeywordLoc(KeywordLoc), LParenLoc(LParenLoc), Base(Base),
        RParenLoc(RParenLoc) { }
  
    Expr *getBase() const { return Base; }
    void setBase(Expr *base) { Base = base; }
  
    SourceLoc getLoc() const { return KeywordLoc; }
    SourceRange getSourceRange() const {
      return SourceRange(KeywordLoc, RParenLoc);
    }
    
    SourceLoc getStartLoc() const {
      return KeywordLoc;
    }
    SourceLoc getEndLoc() const {
      return RParenLoc;
    }
  
    static bool classof(const Expr *E) {
      return E->getKind() == ExprKind::DynamicType;
    }
  };
  
  /// An expression referring to an opaque object of a fixed type.
  ///
  /// Opaque value expressions occur when a particular value within the AST
  /// needs to be re-used without being re-evaluated or for a value that is
  /// a placeholder. OpaqueValueExpr nodes are introduced by some other AST
  /// node (say, a \c DynamicMemberRefExpr) and can only be used within the
  /// subexpressions of that AST node.
  class OpaqueValueExpr : public Expr {
    SourceLoc Loc;
  
  public:
    explicit OpaqueValueExpr(SourceLoc Loc, Type Ty)
      : Expr(ExprKind::OpaqueValue, /*Implicit=*/true, Ty), Loc(Loc) { }
  
    SourceRange getSourceRange() const { return Loc; }
    
    static bool classof(const Expr *E) {
      return E->getKind() == ExprKind::OpaqueValue; 
    }
  };
  
  /// ApplyExpr - Superclass of various function calls, which apply an argument to
  /// a function to get a result.
  class ApplyExpr : public Expr {
    /// The function being called.
    Expr *Fn;
  
    /// The argument being passed to it, and whether it's a 'super' argument.
    llvm::PointerIntPair<Expr *, 1, bool> ArgAndIsSuper;
    
    /// Returns true if \c e could be used as the call's argument. For most \c ApplyExpr
    /// subclasses, this means it is a \c ParenExpr, \c TupleExpr, or 
    /// \c TupleShuffleExpr.
    bool validateArg(Expr *e) const;
  
  protected:
    ApplyExpr(ExprKind Kind, Expr *Fn, Expr *Arg, bool Implicit, Type Ty = Type())
      : Expr(Kind, Implicit, Ty), Fn(Fn), ArgAndIsSuper(Arg, false) {
      assert(classof((Expr*)this) && "ApplyExpr::classof out of date");
      assert(validateArg(Arg) && "Arg is not a permitted expr kind");
      Bits.ApplyExpr.ThrowsIsSet = false;
    }
  
  public:
    Expr *getFn() const { return Fn; }
    void setFn(Expr *e) { Fn = e; }
    Expr *getSemanticFn() const { return Fn->getSemanticsProvidingExpr(); }
    
    Expr *getArg() const { return ArgAndIsSuper.getPointer(); }
    void setArg(Expr *e) {
      assert(validateArg(e) && "Arg is not a permitted expr kind");
      ArgAndIsSuper = {e, ArgAndIsSuper.getInt()};
    }
    
    bool isSuper() const { return ArgAndIsSuper.getInt(); }
    void setIsSuper(bool super) {
      ArgAndIsSuper = {ArgAndIsSuper.getPointer(), super};
    }
  
    /// Has the type-checker set the 'throws' bit yet?
    ///
    /// In general, this should only be used for debugging purposes.
    bool isThrowsSet() const { return Bits.ApplyExpr.ThrowsIsSet; }
  
    /// Does this application throw?  This is only meaningful after
    /// complete type-checking.
    ///
    /// If true, the function expression must have a throwing function
    /// type.  The converse is not true because of 'rethrows' functions.
    bool throws() const {
      assert(Bits.ApplyExpr.ThrowsIsSet);
      return Bits.ApplyExpr.Throws;
    }
    void setThrows(bool throws) {
      assert(!Bits.ApplyExpr.ThrowsIsSet);
      Bits.ApplyExpr.ThrowsIsSet = true;
      Bits.ApplyExpr.Throws = throws;
    }
  
    ValueDecl *getCalledValue() const;
  
    /// Retrieve the argument labels provided at the call site.
    ///
    /// \param scratch Scratch space that will be used when the argument labels
    /// aren't already stored in the AST context.
    ArrayRef<Identifier>
    getArgumentLabels(SmallVectorImpl<Identifier> &scratch) const;
  
    /// Whether this application was written using a trailing closure.
    bool hasTrailingClosure() const;
  
    static bool classof(const Expr *E) {
      return E->getKind() >= ExprKind::First_ApplyExpr &&
             E->getKind() <= ExprKind::Last_ApplyExpr;
    }
  };
    
  /// CallExpr - Application of an argument to a function, which occurs
  /// syntactically through juxtaposition with a TupleExpr whose
  /// leading '(' is unspaced.
  class CallExpr final : public ApplyExpr,
                         public TrailingCallArguments<CallExpr> {
    friend TrailingCallArguments;
  
    CallExpr(Expr *fn, Expr *arg, bool Implicit,
             ArrayRef<Identifier> argLabels,
             ArrayRef<SourceLoc> argLabelLocs,
             bool hasTrailingClosure,
             Type ty);
  
  public:
    /// Create a new call expression.
    ///
    /// Note: prefer to use the entry points that separate out the arguments.
    static CallExpr *
    create(ASTContext &ctx, Expr *fn, Expr *arg, ArrayRef<Identifier> argLabels,
           ArrayRef<SourceLoc> argLabelLocs, bool hasTrailingClosure,
           bool implicit, Type type = Type(),
           llvm::function_ref<Type(const Expr *)> getType =
               [](const Expr *E) -> Type { return E->getType(); });
  
    /// Create a new implicit call expression without any source-location
    /// information.
    ///
    /// \param fn The function being called
    /// \param args The call arguments, not including a trailing closure (if any).
    /// \param argLabels The argument labels, whose size must equal args.size(),
    /// or which must be empty.
    static CallExpr *
    createImplicit(ASTContext &ctx, Expr *fn, ArrayRef<Expr *> args,
                   ArrayRef<Identifier> argLabels,
                   llvm::function_ref<Type(const Expr *)> getType =
                       [](const Expr *E) -> Type { return E->getType(); }) {
      return create(ctx, fn, SourceLoc(), args, argLabels, { }, SourceLoc(),
                    /*trailingClosure=*/nullptr, /*implicit=*/true, getType);
    }
  
    /// Create a new call expression.
    ///
    /// \param fn The function being called
    /// \param args The call arguments, not including a trailing closure (if any).
    /// \param argLabels The argument labels, whose size must equal args.size(),
    /// or which must be empty.
    /// \param argLabelLocs The locations of the argument labels, whose size must
    /// equal args.size() or which must be empty.
    /// \param trailingClosure The trailing closure, if any.
    static CallExpr *
    create(ASTContext &ctx, Expr *fn, SourceLoc lParenLoc, ArrayRef<Expr *> args,
           ArrayRef<Identifier> argLabels, ArrayRef<SourceLoc> argLabelLocs,
           SourceLoc rParenLoc, Expr *trailingClosure, bool implicit,
           llvm::function_ref<Type(const Expr *)> getType =
               [](const Expr *E) -> Type { return E->getType(); });
  
    SourceLoc getStartLoc() const {
      SourceLoc fnLoc = getFn()->getStartLoc();
      return (fnLoc.isValid() ? fnLoc : getArg()->getStartLoc());
    }
    SourceLoc getEndLoc() const {
      SourceLoc argLoc = getArg()->getEndLoc();
      return (argLoc.isValid() ? argLoc : getFn()->getEndLoc());
    }
    
    SourceLoc getLoc() const { 
      SourceLoc FnLoc = getFn()->getLoc(); 
      return FnLoc.isValid() ? FnLoc : getArg()->getLoc();
    }
  
    unsigned getNumArguments() const { return Bits.CallExpr.NumArgLabels; }
    bool hasArgumentLabelLocs() const { return Bits.CallExpr.HasArgLabelLocs; }
  
    /// Whether this call with written with a trailing closure.
    bool hasTrailingClosure() const { return Bits.CallExpr.HasTrailingClosure; }
  
    using TrailingCallArguments::getArgumentLabels;
  
    /// Retrieve the expression that directly represents the callee.
    ///
    /// The "direct" callee is the expression representing the callee
    /// after looking through top-level constructs that don't affect the
    /// identity of the callee, e.g., extra parentheses, optional
    /// unwrapping (?)/forcing (!), etc.
    Expr *getDirectCallee() const;
  
    static bool classof(const Expr *E) { return E->getKind() == ExprKind::Call; }
  };
    
  /// PrefixUnaryExpr - Prefix unary expressions like '!y'.
  class PrefixUnaryExpr : public ApplyExpr {
  public:
    PrefixUnaryExpr(Expr *Fn, Expr *Arg, Type Ty = Type())
      : ApplyExpr(ExprKind::PrefixUnary, Fn, Arg, /*Implicit=*/false, Ty) {}
  
    SourceLoc getLoc() const { return getFn()->getStartLoc(); }
  
    SourceLoc getStartLoc() const {
      return getFn()->getStartLoc();
    }
    SourceLoc getEndLoc() const {
      return getArg()->getEndLoc();
    }
  
    static bool classof(const Expr *E) {
      return E->getKind() == ExprKind::PrefixUnary;
    }
  };
  
  /// PostfixUnaryExpr - Postfix unary expressions like 'y!'.
  class PostfixUnaryExpr : public ApplyExpr {
  public:
    PostfixUnaryExpr(Expr *Fn, Expr *Arg, Type Ty = Type())
      : ApplyExpr(ExprKind::PostfixUnary, Fn, Arg, /*Implicit=*/false, Ty) {}
  
    SourceLoc getLoc() const { return getFn()->getStartLoc(); }
    
    SourceLoc getStartLoc() const {
      return getArg()->getStartLoc();
    }
    SourceLoc getEndLoc() const {
      return getFn()->getEndLoc();
    }
  
    static bool classof(const Expr *E) {
      return E->getKind() == ExprKind::PostfixUnary;
    }
  };
    
  /// BinaryExpr - Infix binary expressions like 'x+y'.  The argument is always
  /// an implicit tuple expression of the type expected by the function.
  class BinaryExpr : public ApplyExpr {
  public:
    BinaryExpr(Expr *Fn, TupleExpr *Arg, bool Implicit, Type Ty = Type())
      : ApplyExpr(ExprKind::Binary, Fn, Arg, Implicit, Ty) {}
  
    SourceLoc getLoc() const { return getFn()->getLoc(); }
  
    SourceRange getSourceRange() const { return getArg()->getSourceRange(); }
    SourceLoc getStartLoc() const { return getArg()->getStartLoc(); }
    SourceLoc getEndLoc() const { return getArg()->getEndLoc(); }
  
    TupleExpr *getArg() const { return cast<TupleExpr>(ApplyExpr::getArg()); }
  
    static bool classof(const Expr *E) { return E->getKind() == ExprKind::Binary;}
  };
  
  /// SelfApplyExpr - Abstract application that provides the 'self' pointer for
  /// a method curried as (this : Self) -> (params) -> result.
  ///
  /// The application of a curried method to 'self' semantically differs from
  /// normal function application because the 'self' parameter can be implicitly
  /// materialized from an rvalue.
  class SelfApplyExpr : public ApplyExpr {
  protected:
    SelfApplyExpr(ExprKind K, Expr *FnExpr, Expr *BaseExpr, Type Ty)
      : ApplyExpr(K, FnExpr, BaseExpr, FnExpr->isImplicit(), Ty) { }
    
  public:
    Expr *getBase() const { return getArg(); }
    void setBase(Expr *E) { setArg(E); }
  
    static bool classof(const Expr *E) {
      return E->getKind() >= ExprKind::First_SelfApplyExpr &&
             E->getKind() <= ExprKind::Last_SelfApplyExpr;
    }
  };
  
  /// DotSyntaxCallExpr - Refer to a method of a type, e.g. P.x.  'x'
  /// is modeled as a DeclRefExpr or OverloadSetRefExpr on the method.
  class DotSyntaxCallExpr : public SelfApplyExpr {
    SourceLoc DotLoc;
    
  public:
    DotSyntaxCallExpr(Expr *FnExpr, SourceLoc DotLoc, Expr *BaseExpr,
                      Type Ty = Type())
      : SelfApplyExpr(ExprKind::DotSyntaxCall, FnExpr, BaseExpr, Ty),
        DotLoc(DotLoc) {
      setImplicit(DotLoc.isInvalid());
    }
  
    SourceLoc getDotLoc() const { return DotLoc; }
  
    SourceLoc getLoc() const {
      return isImplicit() ? getBase()->getStartLoc() : getFn()->getLoc();
    }
    SourceLoc getStartLoc() const {
      return getBase()->getStartLoc();
    }
    SourceLoc getEndLoc() const {
      return isImplicit() ? getBase()->getEndLoc() : getFn()->getEndLoc();
    }
    
    static bool classof(const Expr *E) {
      return E->getKind() == ExprKind::DotSyntaxCall;
    }
  };
  
  /// ConstructorRefCallExpr - Refer to a constructor for a type P.  The
  /// actual reference to function which returns the constructor is modeled
  /// as a DeclRefExpr.
  class ConstructorRefCallExpr : public SelfApplyExpr {
  public:
    ConstructorRefCallExpr(Expr *FnExpr, Expr *BaseExpr, Type Ty = Type())
      : SelfApplyExpr(ExprKind::ConstructorRefCall, FnExpr, BaseExpr, Ty) {}
  
    SourceLoc getLoc() const { return getFn()->getLoc(); }
    SourceLoc getStartLoc() const { return getBase()->getStartLoc(); }
    SourceLoc getEndLoc() const { return getFn()->getEndLoc(); }
    
    static bool classof(const Expr *E) {
      return E->getKind() == ExprKind::ConstructorRefCall;
    }
  };
    
  /// DotSyntaxBaseIgnoredExpr - When a.b resolves to something that does not need
  /// the actual value of the base (e.g. when applied to a metatype, module, or
  /// the base of a 'static' function) this expression node is created.  The
  /// semantics are that its base is evaluated and discarded, then 'b' is
  /// evaluated and returned as the result of the expression.
  class DotSyntaxBaseIgnoredExpr : public Expr {
    Expr *LHS;
    SourceLoc DotLoc;
    Expr *RHS;
  public:
    DotSyntaxBaseIgnoredExpr(Expr *LHS, SourceLoc DotLoc, Expr *RHS, Type rhsTy)
      : Expr(ExprKind::DotSyntaxBaseIgnored, /*Implicit=*/false, rhsTy),
        LHS(LHS), DotLoc(DotLoc), RHS(RHS) {
    }
    
    Expr *getLHS() const { return LHS; }
    void setLHS(Expr *E) { LHS = E; }
    SourceLoc getDotLoc() const { return DotLoc; }
    Expr *getRHS() const { return RHS; }
    void setRHS(Expr *E) { RHS = E; }
  
    SourceLoc getStartLoc() const {
      return DotLoc.isValid() ? LHS->getStartLoc() : RHS->getStartLoc();
    }
    SourceLoc getEndLoc() const { return RHS->getEndLoc(); }
  
    static bool classof(const Expr *E) {
      return E->getKind() == ExprKind::DotSyntaxBaseIgnored;
    }
  };
    
  /// Represents an explicit cast, 'a as T' or 'a is T', where "T" is a
  /// type, and "a" is the expression that will be converted to the type.
  class ExplicitCastExpr : public Expr {
    Expr *SubExpr;
    SourceLoc AsLoc;
    TypeLoc CastTy;
  
  protected:
    ExplicitCastExpr(ExprKind kind, Expr *sub, SourceLoc AsLoc, TypeLoc castTy,
                     Type resultTy)
      : Expr(kind, /*Implicit=*/false), SubExpr(sub), AsLoc(AsLoc), CastTy(castTy)
    {}
  
  public:
    Expr *getSubExpr() const { return SubExpr; }
    
    /// Get the type syntactically spelled in the cast. For some forms of checked
    /// cast this is different from the result type of the expression.
    TypeLoc &getCastTypeLoc() { return CastTy; }
  
    /// Get the type syntactically spelled in the cast. For some forms of checked
    /// cast this is different from the result type of the expression.
    TypeLoc getCastTypeLoc() const { return CastTy; }
  
    void setSubExpr(Expr *E) { SubExpr = E; }
  
    SourceLoc getLoc() const {
      if (AsLoc.isValid())
        return AsLoc;
  
      return SubExpr->getLoc();
    }
  
    SourceLoc getAsLoc() const {
      return AsLoc;
    }
  
    SourceRange getSourceRange() const {
      SourceRange castTyRange = CastTy.getSourceRange();
      if (castTyRange.isInvalid())
        return SubExpr->getSourceRange();
      
      auto startLoc = SubExpr ? SubExpr->getStartLoc() : AsLoc;
      auto endLoc = castTyRange.End;
      
      return {startLoc, endLoc};
    }
    
    /// True if the node has been processed by SequenceExpr folding.
    bool isFolded() const { return SubExpr; }
    
    static bool classof(const Expr *E) {
      return E->getKind() >= ExprKind::First_ExplicitCastExpr &&
             E->getKind() <= ExprKind::Last_ExplicitCastExpr;
    }
  };
  
  /// Return a string representation of a CheckedCastKind.
  StringRef getCheckedCastKindName(CheckedCastKind kind);
    
  /// Abstract base class for checked casts 'as' and 'is'. These represent
  /// casts that can dynamically fail.
  class CheckedCastExpr : public ExplicitCastExpr {
  public:
    CheckedCastExpr(ExprKind kind,
                    Expr *sub, SourceLoc asLoc, TypeLoc castTy, Type resultTy)
      : ExplicitCastExpr(kind, sub, asLoc, castTy, resultTy)
    {
      Bits.CheckedCastExpr.CastKind = unsigned(CheckedCastKind::Unresolved);
    }
    
    /// Return the semantic kind of cast performed.
    CheckedCastKind getCastKind() const {
      return CheckedCastKind(Bits.CheckedCastExpr.CastKind);
    }
    void setCastKind(CheckedCastKind kind) {
      Bits.CheckedCastExpr.CastKind = unsigned(kind);
    }
    
    /// True if the cast has been type-checked and its kind has been set.
    bool isResolved() const {
      return getCastKind() >= CheckedCastKind::First_Resolved;
    }
    
    static bool classof(const Expr *E) {
      return E->getKind() >= ExprKind::First_CheckedCastExpr
          && E->getKind() <= ExprKind::Last_CheckedCastExpr;
    }
  };
  
  /// Represents an explicit forced checked cast, which converts
  /// from a value of some type to some specified subtype and fails dynamically
  /// if the value does not have that type.
  /// Spelled 'a as! T' and produces a value of type 'T'.
  class ForcedCheckedCastExpr : public CheckedCastExpr {
    SourceLoc ExclaimLoc;
  
  public:
    ForcedCheckedCastExpr(Expr *sub, SourceLoc asLoc, SourceLoc exclaimLoc,
                          TypeLoc type)
      : CheckedCastExpr(ExprKind::ForcedCheckedCast,
                        sub, asLoc, type, type.getType()),
        ExclaimLoc(exclaimLoc)
    {
    }
  
    ForcedCheckedCastExpr(SourceLoc asLoc, SourceLoc exclaimLoc, TypeLoc type)
      : ForcedCheckedCastExpr(nullptr, asLoc, exclaimLoc, type)
    {
    }
  
    /// Retrieve the location of the '!' that follows 'as'.
    SourceLoc getExclaimLoc() const { return ExclaimLoc; }
  
    static bool classof(const Expr *E) {
      return E->getKind() == ExprKind::ForcedCheckedCast;
    }
  };
  
  /// Represents an explicit conditional checked cast, which converts
  /// from a type to some subtype and produces an Optional value, which will be
  /// .Some(x) if the cast succeeds, or .None if the cast fails.
  /// Spelled 'a as? T' and produces a value of type 'T?'.
  class ConditionalCheckedCastExpr : public CheckedCastExpr {
    SourceLoc QuestionLoc;
  
  public:
    ConditionalCheckedCastExpr(Expr *sub, SourceLoc asLoc, SourceLoc questionLoc,
                               TypeLoc type)
      : CheckedCastExpr(ExprKind::ConditionalCheckedCast,
                        sub, asLoc, type, type.getType()),
        QuestionLoc(questionLoc)
    { }
    
    ConditionalCheckedCastExpr(SourceLoc asLoc, SourceLoc questionLoc,
                               TypeLoc type)
      : ConditionalCheckedCastExpr(nullptr, asLoc, questionLoc, type)
    {}
  
    /// Retrieve the location of the '?' that follows 'as'.
    SourceLoc getQuestionLoc() const { return QuestionLoc; }
  
    static bool classof(const Expr *E) {
      return E->getKind() == ExprKind::ConditionalCheckedCast;
    }
  };
  
  /// Represents a runtime type check query, 'a is T', where 'T' is a type
  /// and 'a' is a value of some related type. Evaluates to a Bool true if 'a' is
  /// of the type and 'a as T' would succeed, false otherwise.
  ///
  /// FIXME: We should support type queries with a runtime metatype value too.
  class IsExpr : public CheckedCastExpr {
  public:
    IsExpr(Expr *sub, SourceLoc isLoc, TypeLoc type)
      : CheckedCastExpr(ExprKind::Is,
                        sub, isLoc, type, Type())
    {}
    
    IsExpr(SourceLoc isLoc, TypeLoc type)
      : IsExpr(nullptr, isLoc, type)
    {}
    
    static bool classof(const Expr *E) {
      return E->getKind() == ExprKind::Is;
    }
  };
  
  /// Represents an explicit coercion from a value to a specific type.
  ///
  /// Spelled 'a as T' and produces a value of type 'T'.
  class CoerceExpr : public ExplicitCastExpr {
    /// Since there is already `asLoc` location,
    /// we use it to store `start` of the initializer
    /// call source range to save some storage.
    SourceLoc InitRangeEnd;
  
  public:
    CoerceExpr(Expr *sub, SourceLoc asLoc, TypeLoc type)
      : ExplicitCastExpr(ExprKind::Coerce, sub, asLoc, type, type.getType())
    { }
  
    CoerceExpr(SourceLoc asLoc, TypeLoc type)
      : CoerceExpr(nullptr, asLoc, type)
    { }
  
  private:
    CoerceExpr(SourceRange initRange, Expr *literal, TypeLoc type)
      : ExplicitCastExpr(ExprKind::Coerce, literal, initRange.Start,
                         type, type.getType()), InitRangeEnd(initRange.End)
    { setImplicit(); }
  
  public:
    /// Create an implicit coercion expression for literal initialization
    /// preserving original source information, this way original call
    /// could be recreated if needed.
    static CoerceExpr *forLiteralInit(ASTContext &ctx, Expr *literal,
                                      SourceRange range, TypeLoc literalType) {
      return new (ctx) CoerceExpr(range, literal, literalType);
    }
  
    bool isLiteralInit() const { return InitRangeEnd.isValid(); }
  
    SourceRange getSourceRange() const {
      return isLiteralInit()
              ? SourceRange(getAsLoc(), InitRangeEnd)
              : ExplicitCastExpr::getSourceRange();
    }
  
    static bool classof(const Expr *E) {
      return E->getKind() == ExprKind::Coerce;
    }
  };
  
  /// Represents two expressions joined by the arrow operator '->', which
  /// may be preceded by the 'throws' keyword. Currently this only exists to be
  /// transformed into a FunctionTypeRepr by simplifyTypeExpr() in Sema.
  class ArrowExpr : public Expr {
    SourceLoc ThrowsLoc;
    SourceLoc ArrowLoc;
    Expr *Args;
    Expr *Result;
  public:
    ArrowExpr(Expr *Args, SourceLoc ThrowsLoc, SourceLoc ArrowLoc, Expr *Result)
      : Expr(ExprKind::Arrow, /*implicit=*/false, Type()),
        ThrowsLoc(ThrowsLoc), ArrowLoc(ArrowLoc), Args(Args), Result(Result)
    { }
  
    ArrowExpr(SourceLoc ThrowsLoc, SourceLoc ArrowLoc)
      : Expr(ExprKind::Arrow, /*implicit=*/false, Type()),
        ThrowsLoc(ThrowsLoc), ArrowLoc(ArrowLoc), Args(nullptr), Result(nullptr)
    { }
  
    Expr *getArgsExpr() const { return Args; }
    void setArgsExpr(Expr *E) { Args = E; }
    Expr *getResultExpr() const { return Result; }
    void setResultExpr(Expr *E) { Result = E; }
    SourceLoc getThrowsLoc() const { return ThrowsLoc; }
    SourceLoc getArrowLoc() const { return ArrowLoc; }
    bool isFolded() const { return Args != nullptr && Result != nullptr; }
  
    SourceLoc getSourceLoc() const { return ArrowLoc; }
    SourceLoc getStartLoc() const {
      return isFolded() ? Args->getStartLoc() :
             ThrowsLoc.isValid() ? ThrowsLoc : ArrowLoc;
    }
    SourceLoc getEndLoc() const {
      return isFolded() ? Result->getEndLoc() : ArrowLoc;
    }
  
    static bool classof(const Expr *E) {
      return E->getKind() == ExprKind::Arrow;
    }
  };
  
  /// Represents the rebinding of 'self' in a constructor that calls out
  /// to another constructor. The result of the subexpression is assigned to
  /// 'self', and the expression returns void.
  ///
  /// When a super.init or delegating initializer is invoked, 'self' is
  /// reassigned to the result of the initializer (after being downcast in the
  /// case of super.init).
  ///
  /// This is needed for reference types with ObjC interop, where
  /// reassigning 'self' is a supported feature, and for value type delegating
  /// constructors, where the delegatee constructor is responsible for
  /// initializing 'self' in-place before the delegator's logic executes.
  class RebindSelfInConstructorExpr : public Expr {
    Expr *SubExpr;
    VarDecl *Self;
  public:
    RebindSelfInConstructorExpr(Expr *SubExpr, VarDecl *Self);
    
    SWIFT_FORWARD_SOURCE_LOCS_TO(SubExpr)
    
    VarDecl *getSelf() const { return Self; }
    Expr *getSubExpr() const { return SubExpr; }
    void setSubExpr(Expr *Sub) { SubExpr = Sub; }
  
    OtherConstructorDeclRefExpr *getCalledConstructor(bool &isChainToSuper) const;
    
    static bool classof(const Expr *E) {
      return E->getKind() == ExprKind::RebindSelfInConstructor;
    }
  };
    
  /// The conditional expression 'x ? y : z'.
  class IfExpr : public Expr {
    Expr *CondExpr, *ThenExpr, *ElseExpr;
    SourceLoc QuestionLoc, ColonLoc;
  public:
    IfExpr(Expr *CondExpr,
           SourceLoc QuestionLoc, Expr *ThenExpr,
           SourceLoc ColonLoc, Expr *ElseExpr,
           Type Ty = Type())
      : Expr(ExprKind::If, /*Implicit=*/false, Ty),
        CondExpr(CondExpr), ThenExpr(ThenExpr), ElseExpr(ElseExpr),
        QuestionLoc(QuestionLoc), ColonLoc(ColonLoc)
    {}
    
    IfExpr(SourceLoc QuestionLoc, Expr *ThenExpr, SourceLoc ColonLoc)
      : IfExpr(nullptr, QuestionLoc, ThenExpr, ColonLoc, nullptr)
    {}
    
    SourceLoc getLoc() const { return QuestionLoc; }
    SourceLoc getStartLoc() const {
      return (isFolded() ? CondExpr->getStartLoc() : QuestionLoc);
    }
    SourceLoc getEndLoc() const {
      return (isFolded() ? ElseExpr->getEndLoc() : ColonLoc);
    }
    SourceLoc getQuestionLoc() const { return QuestionLoc; }
    SourceLoc getColonLoc() const { return ColonLoc; }
    
    Expr *getCondExpr() const { return CondExpr; }
    void setCondExpr(Expr *E) { CondExpr = E; }
    
    Expr *getThenExpr() const { return ThenExpr; }
    void setThenExpr(Expr *E) { ThenExpr = E; }
    
    Expr *getElseExpr() const { return ElseExpr; }
    void setElseExpr(Expr *E) { ElseExpr = E; }
    
    /// True if the node has been processed by binary expression folding.
    bool isFolded() const { return CondExpr && ElseExpr; }
    
    static bool classof(const Expr *E) {
      return E->getKind() == ExprKind::If;
    }
  };
  
  /// EnumIsCaseExpr - A boolean expression that is true if an enum value is of
  /// a particular case.
  class EnumIsCaseExpr : public Expr {
    Expr *SubExpr;
    EnumElementDecl *Element;
    
  public:
    EnumIsCaseExpr(Expr *SubExpr, EnumElementDecl *Element)
      : Expr(ExprKind::EnumIsCase, /*implicit*/ true),
        SubExpr(SubExpr), Element(Element)
    {}
    
    Expr *getSubExpr() const { return SubExpr; }
    void setSubExpr(Expr *e) { SubExpr = e; }
    
    EnumElementDecl *getEnumElement() const { return Element; }
    void setEnumElement(EnumElementDecl *elt) { Element = elt; }
    
    SourceLoc getLoc() const { return SubExpr->getLoc(); }
    SourceLoc getStartLoc() const { return SubExpr->getStartLoc(); }
    SourceLoc getEndLoc() const { return SubExpr->getEndLoc(); }
    
    static bool classof(const Expr *E) {
      return E->getKind() == ExprKind::EnumIsCase;
    }
  };
  
  /// AssignExpr - A value assignment, like "x = y".
  class AssignExpr : public Expr {
    Expr *Dest;
    Expr *Src;
    SourceLoc EqualLoc;
  
  public:  
    AssignExpr(Expr *Dest, SourceLoc EqualLoc, Expr *Src, bool Implicit)
      : Expr(ExprKind::Assign, Implicit),
        Dest(Dest), Src(Src), EqualLoc(EqualLoc) {}
    
    AssignExpr(SourceLoc EqualLoc)
      : AssignExpr(nullptr, EqualLoc, nullptr, /*Implicit=*/false)
    {}
  
    Expr *getDest() const { return Dest; }
    void setDest(Expr *e) { Dest = e; }
    Expr *getSrc() const { return Src; }
    void setSrc(Expr *e) { Src = e; }
    
    SourceLoc getEqualLoc() const { return EqualLoc; }
    
    SourceLoc getLoc() const {
      SourceLoc loc = EqualLoc;
      if (loc.isValid()) {
        return loc;
      }
      return getStartLoc();
    }
    SourceLoc getStartLoc() const {
      if (!isFolded()) return EqualLoc;
      return ( Dest->getStartLoc().isValid()
             ? Dest->getStartLoc()
             : Src->getStartLoc());
    }
    SourceLoc getEndLoc() const {
      if (!isFolded()) return EqualLoc;
      return (Src->getEndLoc().isValid() ? Src->getEndLoc() : Dest->getEndLoc());
    }
    
    /// True if the node has been processed by binary expression folding.
    bool isFolded() const { return Dest && Src; }
    
    static bool classof(const Expr *E) {
      return E->getKind() == ExprKind::Assign;
    }
  };
  
  /// A pattern production that has been parsed but hasn't been resolved
  /// into a complete pattern. Name binding converts these into standalone pattern
  /// nodes or raises an error if a pattern production appears in an invalid
  /// position.
  class UnresolvedPatternExpr : public Expr {
    Pattern *subPattern;
  
  public:
    explicit UnresolvedPatternExpr(Pattern *subPattern)
      : Expr(ExprKind::UnresolvedPattern, /*Implicit=*/false),
        subPattern(subPattern) { }
    
    const Pattern *getSubPattern() const { return subPattern; }
    Pattern *getSubPattern() { return subPattern; }
    void setSubPattern(Pattern *p) { subPattern = p; }
    
    SourceRange getSourceRange() const;
    SourceLoc getStartLoc() const;
    SourceLoc getEndLoc() const;
    SourceLoc getLoc() const;
    
    static bool classof(const Expr *E) {
      return E->getKind() == ExprKind::UnresolvedPattern;
    }
  };
  
  
  /// An editor placeholder (<#such as this#>) that occurred in an expression
  /// context. If the placeholder is a typed one (see \c EditorPlaceholderData)
  /// its type string will be typechecked and will be associated with this expr.
  class EditorPlaceholderExpr : public Expr {
    Identifier Placeholder;
    SourceLoc Loc;
    TypeLoc PlaceholderTy;
    TypeRepr *ExpansionTyR;
    Expr *SemanticExpr;
  
  public:
    EditorPlaceholderExpr(Identifier Placeholder, SourceLoc Loc,
                          TypeLoc PlaceholderTy,
                          TypeRepr *ExpansionTyR)
      : Expr(ExprKind::EditorPlaceholder, /*Implicit=*/false),
        Placeholder(Placeholder), Loc(Loc),
        PlaceholderTy(PlaceholderTy),
        ExpansionTyR(ExpansionTyR),
        SemanticExpr(nullptr) {
    }
  
    Identifier getPlaceholder() const { return Placeholder; }
    SourceRange getSourceRange() const { return Loc; }
    TypeLoc &getTypeLoc() { return PlaceholderTy; }
    TypeLoc getTypeLoc() const { return PlaceholderTy; }
  
    /// The TypeRepr to be considered for placeholder expansion.
    TypeRepr *getTypeForExpansion() const { return ExpansionTyR; }
  
    static bool classof(const Expr *E) {
      return E->getKind() == ExprKind::EditorPlaceholder;
    }
  
    Expr *getSemanticExpr() const { return SemanticExpr; }
    void setSemanticExpr(Expr *SE) { SemanticExpr = SE; }
  };
  
  /// A LazyInitializerExpr is used to embed an existing typechecked
  /// expression --- like the initializer of a lazy variable --- into an
  /// untypechecked AST.
  class LazyInitializerExpr : public Expr {
    Expr *SubExpr;
  public:
    LazyInitializerExpr(Expr *subExpr)
      : Expr(ExprKind::LazyInitializer, /*implicit*/ true),
        SubExpr(subExpr) {}
  
    SourceRange getSourceRange() const { return SubExpr->getSourceRange(); }
    SourceLoc getStartLoc() const { return SubExpr->getStartLoc(); }
    SourceLoc getEndLoc() const { return SubExpr->getEndLoc(); }
    SourceLoc getLoc() const { return SubExpr->getLoc(); }
  
    Expr *getSubExpr() const { return SubExpr; }
  
    static bool classof(const Expr *E) {
      return E->getKind() == ExprKind::LazyInitializer;
    }
  };
  
  /// Produces the Objective-C selector of the referenced method.
  ///
  /// \code
  /// #selector(UIView.insertSubview(_:aboveSubview:))
  /// \endcode
  class ObjCSelectorExpr : public Expr {
    SourceLoc KeywordLoc;
    SourceLoc LParenLoc;
    SourceLoc ModifierLoc;
    Expr *SubExpr;
    SourceLoc RParenLoc;
    AbstractFunctionDecl *ResolvedMethod = nullptr;
  
  public:
    /// The kind of #selector expression this is.
    enum ObjCSelectorKind {
      Method, Getter, Setter
    };
  
    ObjCSelectorExpr(ObjCSelectorKind kind, SourceLoc keywordLoc,
                     SourceLoc lParenLoc, SourceLoc modifierLoc, Expr *subExpr,
                     SourceLoc rParenLoc)
      : Expr(ExprKind::ObjCSelector, /*Implicit=*/false),
        KeywordLoc(keywordLoc), LParenLoc(lParenLoc),
        ModifierLoc(modifierLoc), SubExpr(subExpr), RParenLoc(rParenLoc) {
      Bits.ObjCSelectorExpr.SelectorKind = static_cast<unsigned>(kind);
    }
  
    Expr *getSubExpr() const { return SubExpr; }
    void setSubExpr(Expr *expr) { SubExpr = expr; }
  
    /// Whether this selector references a property getter or setter.
    bool isPropertySelector() const {
      switch (getSelectorKind()) {
      case ObjCSelectorKind::Method:
        return false;
  
      case ObjCSelectorKind::Getter:
      case ObjCSelectorKind::Setter:
        return true;
      }
  
      llvm_unreachable("Unhandled ObjcSelectorKind in switch.");
    }
  
    /// Whether this selector references a method.
    bool isMethodSelector() const {
      switch (getSelectorKind()) {
      case ObjCSelectorKind::Method:
        return true;
  
      case ObjCSelectorKind::Getter:
      case ObjCSelectorKind::Setter:
        return false;
      }
    }
  
    /// Retrieve the Objective-C method to which this expression refers.
    AbstractFunctionDecl *getMethod() const { return ResolvedMethod; }
  
    /// Set the Objective-C method to which this expression refers.
    void setMethod(AbstractFunctionDecl *method) { ResolvedMethod = method; }
  
    SourceLoc getLoc() const { return KeywordLoc; }
    SourceRange getSourceRange() const {
      return SourceRange(KeywordLoc, RParenLoc);
    }
  
    /// The location at which the getter: or setter: starts. Requires the selector
    /// to be a getter or setter.
    SourceLoc getModifierLoc() const {
      assert(isPropertySelector() && "Modifiers only set on property selectors");
      return ModifierLoc;
    }
  
    /// Retrieve the kind of the selector (method, getter, setter)
    ObjCSelectorKind getSelectorKind() const {
      return static_cast<ObjCSelectorKind>(Bits.ObjCSelectorExpr.SelectorKind);
    }
  
    /// Override the selector kind.
    ///
    /// Used by the type checker to recover from ill-formed #selector
    /// expressions.
    void overrideObjCSelectorKind(ObjCSelectorKind newKind,
                                  SourceLoc modifierLoc) {
      Bits.ObjCSelectorExpr.SelectorKind = static_cast<unsigned>(newKind);
      ModifierLoc = modifierLoc;
    }
  
    static bool classof(const Expr *E) {
      return E->getKind() == ExprKind::ObjCSelector;
    }
  };
  
  /// Produces a keypath string for the given referenced property.
  ///
  /// \code
  /// #keyPath(Person.friends.firstName)
  /// \endcode
  class KeyPathExpr : public Expr {
    SourceLoc StartLoc;
    SourceLoc LParenLoc;
    SourceLoc EndLoc;
    Expr *ObjCStringLiteralExpr = nullptr;
  
    // The parsed root of a Swift keypath (the section before an unusual dot, like
    // Foo.Bar in \Foo.Bar.?.baz).
    Expr *ParsedRoot = nullptr;
    // The parsed path of a Swift keypath (the section after an unusual dot, like
    // ?.baz in \Foo.Bar.?.baz).
    Expr *ParsedPath = nullptr;
  
    // The processed/resolved type, like Foo.Bar in \Foo.Bar.?.baz.
    TypeRepr *RootType = nullptr;
  
  public:
    /// A single stored component, which will be one of:
    /// - an unresolved DeclName, which has to be type-checked
    /// - a resolved ValueDecl, referring to
    /// - a subscript index expression, which may or may not be resolved
    /// - an optional chaining, forcing, or wrapping component
    class Component {
    public:
      enum class Kind: unsigned {
        Invalid,
        UnresolvedProperty,
        UnresolvedSubscript,
        Property,
        Subscript,
        OptionalForce,
        OptionalChain,
        OptionalWrap,
        Identity,
      };
    
    private:
      union DeclNameOrRef {
        DeclName UnresolvedName;
        ConcreteDeclRef ResolvedDecl;
        
        DeclNameOrRef() : UnresolvedName{} {}
        DeclNameOrRef(DeclName un) : UnresolvedName(un) {}
        DeclNameOrRef(ConcreteDeclRef rd) : ResolvedDecl(rd) {}
      } Decl;
      
      
      Expr *SubscriptIndexExpr;
      const Identifier *SubscriptLabelsData;
      const ProtocolConformanceRef *SubscriptHashableConformancesData;
      unsigned SubscriptSize;
      Kind KindValue;
      Type ComponentType;
      SourceLoc Loc;
      
      explicit Component(ASTContext *ctxForCopyingLabels,
                         DeclNameOrRef decl,
                         Expr *indexExpr,
                         ArrayRef<Identifier> subscriptLabels,
                         ArrayRef<ProtocolConformanceRef> indexHashables,
                         Kind kind,
                         Type type,
                         SourceLoc loc);
      
    public:
      Component()
        : Component(nullptr, {}, nullptr, {}, {}, Kind::Invalid,
                    Type(), SourceLoc())
      {}
      
      /// Create an unresolved component for a property.
      static Component forUnresolvedProperty(DeclName UnresolvedName,
                                             SourceLoc Loc) {
        return Component(nullptr,
                         UnresolvedName, nullptr, {}, {},
                         Kind::UnresolvedProperty,
                         Type(),
                         Loc);
      }
      
      /// Create an unresolved component for a subscript.
      static Component forUnresolvedSubscript(ASTContext &ctx,
                                       SourceLoc lSquareLoc,
                                       ArrayRef<Expr *> indexArgs,
                                       ArrayRef<Identifier> indexArgLabels,
                                       ArrayRef<SourceLoc> indexArgLabelLocs,
                                       SourceLoc rSquareLoc,
                                       Expr *trailingClosure);
      
      /// Create an unresolved component for a subscript.
      ///
      /// You shouldn't add new uses of this overload; use the one that takes a
      /// list of index arguments.
      static Component forUnresolvedSubscriptWithPrebuiltIndexExpr(
                                           ASTContext &context,
                                           Expr *index,
                                           ArrayRef<Identifier> subscriptLabels,
                                           SourceLoc loc) {
        
        return Component(&context,
                         {}, index, subscriptLabels, {},
                         Kind::UnresolvedSubscript,
                         Type(), loc);
      }
      
      /// Create an unresolved optional force `!` component.
      static Component forUnresolvedOptionalForce(SourceLoc BangLoc) {
        return Component(nullptr, {}, nullptr, {}, {},
                         Kind::OptionalForce,
                         Type(),
                         BangLoc);
      }
      
      /// Create an unresolved optional chain `?` component.
      static Component forUnresolvedOptionalChain(SourceLoc QuestionLoc) {
        return Component(nullptr, {}, nullptr, {}, {},
                         Kind::OptionalChain,
                         Type(),
                         QuestionLoc);
      }
      
      /// Create a component for a property.
      static Component forProperty(ConcreteDeclRef property,
                                   Type propertyType,
                                   SourceLoc loc) {
        return Component(nullptr, property, nullptr, {}, {},
                         Kind::Property,
                         propertyType,
                         loc);
      }
      
      /// Create a component for a subscript.
      static Component forSubscript(ASTContext &ctx,
                                ConcreteDeclRef subscript,
                                SourceLoc lSquareLoc,
                                ArrayRef<Expr *> indexArgs,
                                ArrayRef<Identifier> indexArgLabels,
                                ArrayRef<SourceLoc> indexArgLabelLocs,
                                SourceLoc rSquareLoc,
                                Expr *trailingClosure,
                                Type elementType,
                                ArrayRef<ProtocolConformanceRef> indexHashables);
  
      /// Create a component for a subscript.
      ///
      /// You shouldn't add new uses of this overload; use the one that takes a
      /// list of index arguments.
      static Component forSubscriptWithPrebuiltIndexExpr(
         ConcreteDeclRef subscript, Expr *index, ArrayRef<Identifier> labels,
         Type elementType, SourceLoc loc,
         ArrayRef<ProtocolConformanceRef> indexHashables);
      
      /// Create an optional-forcing `!` component.
      static Component forOptionalForce(Type forcedType, SourceLoc bangLoc) {
        return Component(nullptr, {}, nullptr, {}, {},
                         Kind::OptionalForce, forcedType,
                         bangLoc);
      }
      
      /// Create an optional-chaining `?` component.
      static Component forOptionalChain(Type unwrappedType,
                                        SourceLoc questionLoc) {
        return Component(nullptr, {}, nullptr, {}, {},
                         Kind::OptionalChain, unwrappedType,
                         questionLoc);
      }
      
      /// Create an optional-wrapping component. This doesn't have a surface
      /// syntax but may appear when the non-optional result of an optional chain
      /// is implicitly wrapped.
      static Component forOptionalWrap(Type wrappedType) {
        return Component(nullptr, {}, nullptr, {}, {},
                         Kind::OptionalWrap, wrappedType,
                         SourceLoc());
      }
      
      static Component forIdentity(SourceLoc selfLoc) {
        return Component(nullptr, {}, nullptr, {}, {},
                         Kind::Identity, Type(),
                         selfLoc);
      }
      
      SourceLoc getLoc() const {
        return Loc;
      }
      
      Kind getKind() const {
        return KindValue;
      }
      
      bool isValid() const {
        return getKind() != Kind::Invalid;
      }
  
      bool isResolved() const {
        if (!getComponentType())
          return false;
  
        switch (getKind()) {
        case Kind::Subscript:
        case Kind::OptionalChain:
        case Kind::OptionalWrap:
        case Kind::OptionalForce:
        case Kind::Property:
        case Kind::Identity:
          return true;
  
        case Kind::UnresolvedSubscript:
        case Kind::UnresolvedProperty:
        case Kind::Invalid:
          return false;
        }
        llvm_unreachable("unhandled kind");
      }
  
      Expr *getIndexExpr() const {
        switch (getKind()) {
        case Kind::Subscript:
        case Kind::UnresolvedSubscript:
          return SubscriptIndexExpr;
  
        case Kind::Invalid:
        case Kind::OptionalChain:
        case Kind::OptionalWrap:
        case Kind::OptionalForce:
        case Kind::UnresolvedProperty:
        case Kind::Property:
        case Kind::Identity:
          return nullptr;
        }
        llvm_unreachable("unhandled kind");
      }
  
      ArrayRef<Identifier> getSubscriptLabels() const {
        switch (getKind()) {
        case Kind::Subscript:
        case Kind::UnresolvedSubscript:
          return {SubscriptLabelsData, (size_t)SubscriptSize};
  
        case Kind::Invalid:
        case Kind::OptionalChain:
        case Kind::OptionalWrap:
        case Kind::OptionalForce:
        case Kind::UnresolvedProperty:
        case Kind::Property:
        case Kind::Identity:
          llvm_unreachable("no subscript labels for this kind");
        }
        llvm_unreachable("unhandled kind");
      }
  
      ArrayRef<ProtocolConformanceRef>
      getSubscriptIndexHashableConformances() const {
        switch (getKind()) {
        case Kind::Subscript:
          if (!SubscriptHashableConformancesData)
            return {};
          return {SubscriptHashableConformancesData, (size_t)SubscriptSize};
  
        case Kind::UnresolvedSubscript:
        case Kind::Invalid:
        case Kind::OptionalChain:
        case Kind::OptionalWrap:
        case Kind::OptionalForce:
        case Kind::UnresolvedProperty:
        case Kind::Property:
        case Kind::Identity:
          return {};
        }
        llvm_unreachable("unhandled kind");
      }
  
      void setSubscriptIndexHashableConformances(
        ArrayRef<ProtocolConformanceRef> hashables);
  
      DeclName getUnresolvedDeclName() const {
        switch (getKind()) {
        case Kind::UnresolvedProperty:
          return Decl.UnresolvedName;
  
        case Kind::Invalid:
        case Kind::Subscript:
        case Kind::UnresolvedSubscript:
        case Kind::OptionalChain:
        case Kind::OptionalWrap:
        case Kind::OptionalForce:
        case Kind::Property:
        case Kind::Identity:
          llvm_unreachable("no unresolved name for this kind");
        }
        llvm_unreachable("unhandled kind");
      }
  
      ConcreteDeclRef getDeclRef() const {
        switch (getKind()) {
        case Kind::Property:
        case Kind::Subscript:
          return Decl.ResolvedDecl;
  
        case Kind::Invalid:
        case Kind::UnresolvedProperty:
        case Kind::UnresolvedSubscript:
        case Kind::OptionalChain:
        case Kind::OptionalWrap:
        case Kind::OptionalForce:
        case Kind::Identity:
          llvm_unreachable("no decl ref for this kind");
        }
        llvm_unreachable("unhandled kind");
      }
  
      Type getComponentType() const {
        return ComponentType;
      }
      
      void setComponentType(Type t) {
        ComponentType = t;
      }
    };
  
  private:
    llvm::MutableArrayRef<Component> Components;
  
  public:
    /// Create a new #keyPath expression.
    KeyPathExpr(ASTContext &C,
                SourceLoc keywordLoc, SourceLoc lParenLoc,
                ArrayRef<Component> components,
                SourceLoc rParenLoc,
                bool isImplicit = false);
  
    KeyPathExpr(SourceLoc backslashLoc, Expr *parsedRoot, Expr *parsedPath,
                bool isImplicit = false)
        : Expr(ExprKind::KeyPath, isImplicit), StartLoc(backslashLoc),
          EndLoc(parsedPath ? parsedPath->getEndLoc() : parsedRoot->getEndLoc()),
          ParsedRoot(parsedRoot), ParsedPath(parsedPath) {
      assert((parsedRoot || parsedPath) &&
             "keypath must have either root or path");
      Bits.KeyPathExpr.IsObjC = false;
    }
  
    SourceLoc getLoc() const { return StartLoc; }
    SourceRange getSourceRange() const { return SourceRange(StartLoc, EndLoc); }
  
    /// Get the components array.
    ArrayRef<Component> getComponents() const {
      return Components;
    }
    MutableArrayRef<Component> getMutableComponents() {
      return Components;
    }
    
    /// Resolve the components of an un-type-checked expr. This copies over the
    /// components from the argument array.
    void resolveComponents(ASTContext &C,
                           ArrayRef<Component> resolvedComponents);
    
    /// Retrieve the string literal expression, which will be \c NULL prior to
    /// type checking and a string literal after type checking for an
    /// @objc key path.
    Expr *getObjCStringLiteralExpr() const {
      return ObjCStringLiteralExpr;
    }
  
    /// Set the semantic expression.
    void setObjCStringLiteralExpr(Expr *expr) {
      ObjCStringLiteralExpr = expr;
    }
  
    Expr *getParsedRoot() const {
      assert(!isObjC() && "cannot get parsed root of ObjC keypath");
      return ParsedRoot;
    }
    void setParsedRoot(Expr *root) {
      assert(!isObjC() && "cannot get parsed root of ObjC keypath");
      ParsedRoot = root;
    }
  
    Expr *getParsedPath() const {
      assert(!isObjC() && "cannot get parsed path of ObjC keypath");
      return ParsedPath;
    }
    void setParsedPath(Expr *path) {
      assert(!isObjC() && "cannot set parsed path of ObjC keypath");
      ParsedPath = path;
    }
  
    TypeRepr *getRootType() const {
      assert(!isObjC() && "cannot get root type of ObjC keypath");
      return RootType;
    }
    void setRootType(TypeRepr *rootType) {
      assert(!isObjC() && "cannot set root type of ObjC keypath");
      RootType = rootType;
    }
  
    /// True if this is an ObjC key path expression.
    bool isObjC() const { return Bits.KeyPathExpr.IsObjC; }
  
    static bool classof(const Expr *E) {
      return E->getKind() == ExprKind::KeyPath;
    }
  };
  
  /// Represents the unusual behavior of a . in a \ keypath expression, such as
  /// \.[0] and \Foo.?.
  class KeyPathDotExpr : public Expr {
    SourceLoc DotLoc;
  
  public:
    KeyPathDotExpr(SourceLoc dotLoc)
        : Expr(ExprKind::KeyPathDot, /*isImplicit=*/true), DotLoc(dotLoc) {}
  
    SourceLoc getLoc() const { return DotLoc; }
    SourceRange getSourceRange() const { return SourceRange(DotLoc, DotLoc); }
  
    static bool classof(const Expr *E) {
      return E->getKind() == ExprKind::KeyPathDot;
    }
  };
  
  inline bool Expr::isInfixOperator() const {
    return isa<BinaryExpr>(this) || isa<IfExpr>(this) ||
           isa<AssignExpr>(this) || isa<ExplicitCastExpr>(this);
  }
    
  inline bool ApplyExpr::validateArg(Expr *e) const {
    if (isa<SelfApplyExpr>(this))
      return true;
    else if (isa<BinaryExpr>(this))
      return isa<TupleExpr>(e);
    else
      return isa<ParenExpr>(e) || isa<TupleExpr>(e) || isa<TupleShuffleExpr>(e);
  }
  
  inline Expr *const *CollectionExpr::getTrailingObjectsPointer() const {
    if (auto ty = dyn_cast<ArrayExpr>(this))
      return ty->getTrailingObjects<Expr*>();
    if (auto ty = dyn_cast<DictionaryExpr>(this))
      return ty->getTrailingObjects<Expr*>();
    llvm_unreachable("Unhandled CollectionExpr!");
  }
  
  inline const SourceLoc *CollectionExpr::getTrailingSourceLocs() const {
    if (auto ty = dyn_cast<ArrayExpr>(this))
      return ty->getTrailingObjects<SourceLoc>();
    if (auto ty = dyn_cast<DictionaryExpr>(this))
      return ty->getTrailingObjects<SourceLoc>();
    llvm_unreachable("Unhandled CollectionExpr!");
  }
  
  #undef SWIFT_FORWARD_SOURCE_LOCS_TO
    
  } // end namespace swift
  
  #endif
  