//===--- Expr.h - Swift Language Expression ASTs ----------------*- C++ -*-===// // // This source file is part of the Swift.org open source project // // Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information // See http://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/DeclContext.h" #include "swift/AST/Identifier.h" #include "swift/AST/Substitution.h" #include "swift/AST/TypeLoc.h" #include "swift/Basic/SourceLoc.h" #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/StringRef.h" namespace llvm { struct fltSemantics; } namespace swift { class ArchetypeType; class ASTContext; class Type; class ValueDecl; class Decl; class Pattern; class SubscriptDecl; class Stmt; class BraceStmt; class ASTWalker; class Initializer; class VarDecl; class OpaqueValueExpr; class ProtocolConformance; class FuncDecl; class ConstructorDecl; class SubstitutableType; class TypeDecl; enum class ExprKind : uint8_t { #define EXPR(Id, Parent) Id, #define EXPR_RANGE(Id, FirstId, LastId) \ First_##Id##Expr = FirstId, Last_##Id##Expr = LastId, #include "swift/AST/ExprNodes.def" }; /// Discriminates the different kinds of checked cast supported. 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 cast from a class to one of its subclasses. Downcast, /// A cast from a class to a type parameter constrained by that class as a /// superclass. SuperToArchetype, /// A cast from a type parameter to another type parameter. ArchetypeToArchetype, /// A cast from a type parameter to a concrete type. ArchetypeToConcrete, /// A cast from an existential type to a type parameter. ExistentialToArchetype, /// A cast from an existential type to a concrete type. ExistentialToConcrete, /// A cast from a concrete type to a type parameter. ConcreteToArchetype, /// A cast from a concrete type to an existential type it is not statically /// known to conform to. ConcreteToUnrelatedExistential, Last_CheckedCastKind = ConcreteToUnrelatedExistential, }; /// Expr - Base class for all expressions in swift. class alignas(8) Expr { Expr(const Expr&) = delete; void operator=(const Expr&) = delete; class ExprBitfields { friend class Expr; /// The subclass of Expr that this is. unsigned Kind : 8; /// Whether the Expr represents something directly written in source or /// it was implicitly generated by the type-checker. unsigned Implicit : 1; }; enum { NumExprBits = 9 }; static_assert(NumExprBits <= 32, "fits in an unsigned"); class LiteralExprBitfields { friend class LiteralExpr; unsigned : NumExprBits; }; enum { NumLiteralExprBits = NumExprBits + 0 }; static_assert(NumLiteralExprBits <= 32, "fits in an unsigned"); class IntegerLiteralExprBitfields { friend class IntegerLiteralExpr; unsigned : NumLiteralExprBits; unsigned IsNegative : 1; }; enum { NumIntegerLiteralExprBits = NumLiteralExprBits + 1 }; static_assert(NumIntegerLiteralExprBits <= 32, "fits in an unsigned"); class StringLiteralExprBitfields { friend class StringLiteralExpr; unsigned : NumLiteralExprBits; unsigned Encoding : 1; unsigned IsSingleExtendedGraphemeCluster : 1; }; enum { NumStringLiteralExprBits = NumLiteralExprBits + 2 }; static_assert(NumStringLiteralExprBits <= 32, "fits in an unsigned"); class DeclRefExprBitfields { friend class DeclRefExpr; unsigned : NumExprBits; unsigned IsDirectPropertyAccess : 1; }; enum { NumDeclRefExprBits = NumExprBits + 1 }; static_assert(NumDeclRefExprBits <= 32, "fits in an unsigned"); class MemberRefExprBitfields { friend class MemberRefExpr; unsigned : NumExprBits; unsigned IsDirectPropertyAccess : 1; unsigned IsSuper : 1; }; enum { NumMemberRefExprBits = NumExprBits + 2 }; static_assert(NumMemberRefExprBits <= 32, "fits in an unsigned"); class TupleExprBitfields { friend class TupleExpr; unsigned : NumExprBits; /// Whether this tuple has a trailing closure. unsigned HasTrailingClosure : 1; /// Whether this tuple has any labels. unsigned HasElementNames : 1; /// Whether this tuple has label locations. unsigned HasElementNameLocations : 1; }; enum { NumTupleExprBits = NumExprBits + 3 }; static_assert(NumTupleExprBits <= 32, "fits in an unsigned"); class SubscriptExprBitfields { friend class SubscriptExpr; unsigned : NumExprBits; unsigned IsSuper : 1; }; enum { NumSubscriptExprBits = NumExprBits + 1 }; static_assert(NumSubscriptExprBits <= 32, "fits in an unsigned"); class MagicIdentifierLiteralExprBitfields { friend class MagicIdentifierLiteralExpr; unsigned : NumLiteralExprBits; unsigned Kind : 2; unsigned StringEncoding : 1; }; enum { NumMagicIdentifierLiteralExprBits = NumLiteralExprBits + 3 }; static_assert(NumMagicIdentifierLiteralExprBits <= 32, "fits in an unsigned"); class AbstractClosureExprBitfields { friend class AbstractClosureExpr; unsigned : NumExprBits; unsigned Discriminator : 16; enum : unsigned { InvalidDiscriminator = 0xFFFF }; }; enum { NumAbstractClosureExprBits = NumExprBits + 16 }; static_assert(NumAbstractClosureExprBits <= 32, "fits in an unsigned"); class ClosureExprBitfields { friend class ClosureExpr; unsigned : NumAbstractClosureExprBits; /// True if closure parameters were synthesized from anonymous closure /// variables. unsigned HasAnonymousClosureVars : 1; }; enum { NumClosureExprBits = NumAbstractClosureExprBits + 1 }; static_assert(NumClosureExprBits <= 32, "fits in an unsigned"); class BindOptionalExprBitfields { friend class BindOptionalExpr; unsigned : NumExprBits; unsigned Depth : 16; }; enum { NumBindOptionalExprBits = NumExprBits + 16 }; static_assert(NumBindOptionalExprBits <= 32, "fits in an unsigned"); enum { NumCheckedCastKindBits = 4 }; class CheckedCastExprBitfields { friend class CheckedCastExpr; unsigned : NumExprBits; unsigned CastKind : NumCheckedCastKindBits; }; enum { NumCheckedCastExprBits = NumExprBits + 4 }; static_assert(NumCheckedCastExprBits <= 32, "fits in an unsigned"); static_assert(unsigned(CheckedCastKind::Last_CheckedCastKind) < (1 << NumCheckedCastKindBits), "unable to fit a CheckedCastKind in the given number of bits"); protected: union { ExprBitfields ExprBits; LiteralExprBitfields LiteralExprBits; IntegerLiteralExprBitfields IntegerLiteralExprBits; StringLiteralExprBitfields StringLiteralExprBits; DeclRefExprBitfields DeclRefExprBits; TupleExprBitfields TupleExprBits; MemberRefExprBitfields MemberRefExprBits; SubscriptExprBitfields SubscriptExprBits; MagicIdentifierLiteralExprBitfields MagicIdentifierLiteralExprBits; AbstractClosureExprBitfields AbstractClosureExprBits; ClosureExprBitfields ClosureExprBits; BindOptionalExprBitfields BindOptionalExprBits; CheckedCastExprBitfields CheckedCastExprBits; }; private: /// Ty - This is the type of the expression. Type Ty; protected: Expr(ExprKind Kind, bool Implicit, Type Ty = Type()) : Ty(Ty) { ExprBits.Kind = unsigned(Kind); ExprBits.Implicit = Implicit; } public: /// Return the kind of this expression. ExprKind getKind() const { return ExprKind(ExprBits.Kind); } /// \brief 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) { Ty = T; } /// \brief Return the source range of the expression. SourceRange getSourceRange() const; /// getStartLoc - Return the location of the start of the expression. SourceLoc getStartLoc() const { return getSourceRange().Start; } /// \brief Retrieve the location of the end of the expression. SourceLoc getEndLoc() const { return getSourceRange().End; } /// getLoc - Return the caret location of this expression. SourceLoc getLoc() const; 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(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(this)->getValueProvidingExpr(); } /// walk - This recursively walks the AST rooted at this expression. Expr *walk(ASTWalker &walker); Expr *walk(ASTWalker &&walker) { return walk(walker); } /// findExistingInitializerContext - Given that this expression is /// an initializer that belongs in some sort of Initializer /// context, look through it for any existing context object. Initializer *findExistingInitializerContext(); /// Determine whether this expression refers to a statically-derived metatype. /// /// A statically-derived metatype is a metatype value that comes from /// referring to a named type directly. bool isStaticallyDerivedMetatype() const; /// isImplicit - Determines whether this expression was implicitly-generated, /// rather than explicitly written in the AST. bool isImplicit() const { return ExprBits.Implicit; } void setImplicit(bool Implicit = true) { ExprBits.Implicit = Implicit; } /// Determine whether this expression is 'super', possibly converted to /// a base class. bool isSuperExpr() const; LLVM_ATTRIBUTE_DEPRECATED( void dump() const LLVM_ATTRIBUTE_USED, "only for use within the debugger"); void dump(raw_ostream &OS) const; void print(raw_ostream &OS, 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; } }; /// 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; } }; /// LiteralExpr - Common base class between the literals. class LiteralExpr : public Expr { public: LiteralExpr(ExprKind Kind, bool Implicit) : Expr(Kind, Implicit) {} static bool classof(const Expr *E) { return E->getKind() >= ExprKind::First_LiteralExpr && E->getKind() <= ExprKind::Last_LiteralExpr; } }; /// \brief 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 LiteralExpr { /// The value of the literal as an ASTContext-owned string. Underscores must /// be stripped. StringRef Val; // Use StringRef instead of APInt, APInt leaks. SourceLoc MinusLoc; SourceLoc DigitsLoc; public: IntegerLiteralExpr(StringRef Val, SourceLoc DigitsLoc, bool Implicit) : LiteralExpr(ExprKind::IntegerLiteral, Implicit), Val(Val), DigitsLoc(DigitsLoc) { IntegerLiteralExprBits.IsNegative = false; } APInt getValue() const; static APInt getValue(StringRef Text, unsigned BitWidth); bool isNegative() const { return IntegerLiteralExprBits.IsNegative; } void setNegative(SourceLoc Loc) { MinusLoc = Loc; IntegerLiteralExprBits.IsNegative = true; } StringRef getDigitsText() const { return Val; } SourceRange getSourceRange() const { if (isNegative()) return { MinusLoc, DigitsLoc }; else return DigitsLoc; } 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 LiteralExpr { /// The value of the literal as an ASTContext-owned string. Underscores must /// be stripped. StringRef Val; // Use StringRef instead of APFloat, APFloat leaks. SourceLoc Loc; public: FloatLiteralExpr(StringRef Val, SourceLoc Loc, bool Implicit) : LiteralExpr(ExprKind::FloatLiteral, Implicit), Val(Val), Loc(Loc) {} APFloat getValue() const; static APFloat getValue(StringRef Text, const llvm::fltSemantics &Semantics); StringRef getText() const { return Val; } SourceRange getSourceRange() const { return Loc; } static bool classof(const Expr *E) { return E->getKind() == ExprKind::FloatLiteral; } }; /// CharacterLiteral - Character literal, like 'x'. After semantic analysis /// assigns types, this is guaranteed to only have a 32-bit BuiltinIntegerType. class CharacterLiteralExpr : public LiteralExpr { uint32_t Val; SourceLoc Loc; public: CharacterLiteralExpr(uint32_t Val, SourceLoc Loc) : LiteralExpr(ExprKind::CharacterLiteral, /*Implicit=*/false), Val(Val), Loc(Loc) {} uint32_t getValue() const { return Val; } SourceRange getSourceRange() const { return Loc; } static bool classof(const Expr *E) { return E->getKind() == ExprKind::CharacterLiteral; } }; /// StringLiteralExpr - String literal, like '"foo"'. After semantic /// analysis assigns types, this is guaranteed to only have a /// BuiltinRawPointerType. class StringLiteralExpr : public LiteralExpr { StringRef Val; SourceRange Range; public: /// The encoding that should be used for the string literal. enum Encoding : unsigned { UTF8, UTF16 }; StringLiteralExpr(StringRef Val, SourceRange Range); 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(StringLiteralExprBits.Encoding); } /// Set the encoding that should be used for this string literal. void setEncoding(Encoding encoding) { StringLiteralExprBits.Encoding = static_cast(encoding); } bool isSingleExtendedGraphemeCluster() const { return StringLiteralExprBits.IsSingleExtendedGraphemeCluster; } static bool classof(const Expr *E) { return E->getKind() == ExprKind::StringLiteral; } }; /// 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 { SourceLoc Loc; MutableArrayRef Segments; Expr *SemanticExpr; public: InterpolatedStringLiteralExpr(SourceLoc Loc, MutableArrayRef Segments) : LiteralExpr(ExprKind::InterpolatedStringLiteral, /*Implicit=*/false), Loc(Loc), Segments(Segments), SemanticExpr() { } MutableArrayRef getSegments() { return Segments; } ArrayRef getSegments() const { return Segments; } /// \brief 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; } SourceRange getSourceRange() const { return Loc; } 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 }; private: SourceLoc Loc; public: MagicIdentifierLiteralExpr(Kind kind, SourceLoc loc, bool implicit) : LiteralExpr(ExprKind::MagicIdentifierLiteral, implicit), Loc(loc) { MagicIdentifierLiteralExprBits.Kind = static_cast(kind); MagicIdentifierLiteralExprBits.StringEncoding = static_cast(StringLiteralExpr::UTF8); } Kind getKind() const { return static_cast(MagicIdentifierLiteralExprBits.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: return false; } } 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( MagicIdentifierLiteralExprBits.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"); MagicIdentifierLiteralExprBits.StringEncoding = static_cast(encoding); } static bool classof(const Expr *E) { return E->getKind() == ExprKind::MagicIdentifierLiteral; } }; /// 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 { /// This is used when the reference is specialized, e.g "GenCls", to /// hold information about the generic arguments. struct SpecializeInfo { ConcreteDeclRef D; ArrayRef GenericArgs; }; /// \brief The declaration pointer or SpecializeInfo pointer if it was /// explicitly specialized with <...>. llvm::PointerUnion DOrSpecialized; SourceLoc Loc; SpecializeInfo *getSpecInfo() const { return DOrSpecialized.dyn_cast(); } public: DeclRefExpr(ConcreteDeclRef D, SourceLoc Loc, bool Implicit, // If True, access to computed properties with storage goes to // the storage, instead of through the accessors. bool UsesDirectPropertyAccess = false, Type Ty = Type()) : Expr(ExprKind::DeclRef, Implicit, Ty), DOrSpecialized(D), Loc(Loc) { DeclRefExprBits.IsDirectPropertyAccess = UsesDirectPropertyAccess; } /// 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. bool isDirectPropertyAccess() const { return DeclRefExprBits.IsDirectPropertyAccess; } /// Retrieve the concrete declaration reference. ConcreteDeclRef getDeclRef() const { if (auto Spec = getSpecInfo()) return Spec->D; return DOrSpecialized.get(); } /// Set the declaration. void setDeclRef(ConcreteDeclRef ref); void setSpecialized(); /// \brief Determine whether this declaration reference was immediately /// specialized by <...>. bool isSpecialized() const { return getSpecInfo() != nullptr; } /// Set the generic arguments. /// /// This copies the array using ASTContext's allocator. void setGenericArgs(ArrayRef GenericArgs); /// Returns the generic arguments if it was specialized or an empty array /// otherwise. ArrayRef getGenericArgs() const { if (auto Spec = getSpecInfo()) return Spec->GenericArgs; return ArrayRef(); } SourceRange getSourceRange() const { return Loc; } 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); // 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); /// Return a TypeExpr for a TypeDecl and the specified location. static TypeExpr *createForDecl(SourceLoc Loc, TypeDecl *D); static TypeExpr *createForSpecializedDecl(SourceLoc Loc, TypeDecl *D, ArrayRef args, SourceRange angleLocs); 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(); } 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; SourceLoc Loc; public: OtherConstructorDeclRefExpr(ConcreteDeclRef Ctor, SourceLoc Loc, bool Implicit, Type Ty = {}) : Expr(ExprKind::OtherConstructorDeclRef, Implicit, Ty), Ctor(Ctor), Loc(Loc) {} ConstructorDecl *getDecl() const; ConcreteDeclRef getDeclRef() const { return Ctor; } SourceLoc getConstructorLoc() const { return Loc; } SourceRange getSourceRange() const { return Loc; } static bool classof(const Expr *E) { return E->getKind() == ExprKind::OtherConstructorDeclRef; } }; /// An unresolved reference to a constructor member of a value. Resolves to a /// DotSyntaxCall involving the value and the resolved constructor. class UnresolvedConstructorExpr : public Expr { Expr *SubExpr; SourceLoc DotLoc; SourceLoc ConstructorLoc; public: UnresolvedConstructorExpr(Expr *SubExpr, SourceLoc DotLoc, SourceLoc ConstructorLoc, bool Implicit) : Expr(ExprKind::UnresolvedConstructor, Implicit), SubExpr(SubExpr), DotLoc(DotLoc), ConstructorLoc(ConstructorLoc) {} Expr *getSubExpr() const { return SubExpr; } void setSubExpr(Expr *e) { SubExpr = e; } SourceLoc getLoc() const { return ConstructorLoc; } SourceLoc getConstructorLoc() const { return ConstructorLoc; } SourceLoc getDotLoc() const { return DotLoc; } SourceRange getSourceRange() const { return SourceRange(SubExpr->getStartLoc(), ConstructorLoc); } static bool classof(const Expr *E) { return E->getKind() == ExprKind::UnresolvedConstructor; } }; /// 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 Decls; protected: OverloadSetRefExpr(ExprKind Kind, ArrayRef decls, bool Implicit, Type Ty) : Expr(Kind, Implicit, Ty), Decls(decls) {} public: ArrayRef getDecls() const { return Decls; } /// 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; 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 : public OverloadSetRefExpr { SourceLoc Loc; bool IsSpecialized = false; bool IsPotentiallyDelayedGlobalOperator = false; public: OverloadedDeclRefExpr(ArrayRef Decls, SourceLoc Loc, bool Implicit, Type Ty = Type()) : OverloadSetRefExpr(ExprKind::OverloadedDeclRef, Decls, Implicit, Ty), Loc(Loc) { } SourceLoc getLoc() const { return Loc; } SourceRange getSourceRange() const { return Loc; } void setSpecialized(bool specialized) { IsSpecialized = specialized; } /// \brief Determine whether this declaration reference was immediately /// specialized by <...>. bool isSpecialized() const { return IsSpecialized; } void setIsPotentiallyDelayedGlobalOperator() { IsPotentiallyDelayedGlobalOperator = true; } bool isPotentiallyDelayedGlobalOperator() const { return IsPotentiallyDelayedGlobalOperator; } static bool classof(const Expr *E) { return E->getKind() == ExprKind::OverloadedDeclRef; } }; /// OverloadedMemberRefExpr - A reference to an overloaded name that is a /// member, relative to some base expression, that will eventually be /// resolved to some kind of member-reference expression. class OverloadedMemberRefExpr : public OverloadSetRefExpr { Expr *SubExpr; SourceLoc DotLoc; SourceLoc MemberLoc; public: OverloadedMemberRefExpr(Expr *SubExpr, SourceLoc DotLoc, ArrayRef Decls, SourceLoc MemberLoc, bool Implicit, Type Ty = Type()) : OverloadSetRefExpr(ExprKind::OverloadedMemberRef, Decls, Implicit, Ty), SubExpr(SubExpr), DotLoc(DotLoc), MemberLoc(MemberLoc) { } SourceLoc getDotLoc() const { return DotLoc; } SourceLoc getMemberLoc() const { return MemberLoc; } Expr *getBase() const { return SubExpr; } void setBase(Expr *E) { SubExpr = E; } SourceLoc getLoc() const { return MemberLoc; } SourceLoc getStartLoc() const { return DotLoc.isValid()? SubExpr->getStartLoc() : MemberLoc; } SourceLoc getEndLoc() const { return MemberLoc; } SourceRange getSourceRange() const { return SourceRange(getStartLoc(), MemberLoc); } static bool classof(const Expr *E) { return E->getKind() == ExprKind::OverloadedMemberRef; } }; /// 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 { Identifier Name; SourceLoc Loc; DeclRefKind RefKind; bool IsSpecialized = false; public: UnresolvedDeclRefExpr(Identifier name, DeclRefKind refKind, SourceLoc loc) : Expr(ExprKind::UnresolvedDeclRef, /*Implicit=*/loc.isInvalid()), Name(name), Loc(loc), RefKind(refKind) { } bool hasName() const { return !Name.empty(); } Identifier getName() const { return Name; } DeclRefKind getRefKind() const { return RefKind; } void setSpecialized(bool specialized) { IsSpecialized = specialized; } /// \brief Determine whether this declaration reference was immediately /// specialized by <...>. bool isSpecialized() const { return IsSpecialized; } SourceRange getSourceRange() const { return Loc; } static bool classof(const Expr *E) { return E->getKind() == ExprKind::UnresolvedDeclRef; } }; /// 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 Expr { Expr *Base; ConcreteDeclRef Member; SourceLoc DotLoc; SourceRange NameRange; public: MemberRefExpr(Expr *base, SourceLoc dotLoc, ConcreteDeclRef member, SourceRange nameRange, bool Implicit, // If True, access to computed properties with storage goes to // the storage, instead of through the accessors. bool UsesDirectPropertyAccess = false); Expr *getBase() const { return Base; } ConcreteDeclRef getMember() const { return Member; } SourceLoc getNameLoc() const { return NameRange.Start; } SourceLoc getDotLoc() const { return DotLoc; } void setBase(Expr *E) { Base = E; } /// Return true if this member access is direct, meaning that it /// does not call the getter or setter. bool isDirectPropertyAccess() const { return MemberRefExprBits.IsDirectPropertyAccess; } /// Determine whether this member reference refers to the /// superclass's property. bool isSuper() const { return MemberRefExprBits.IsSuper; } /// Set whether this member reference refers to the superclass's /// property. void setIsSuper(bool isSuper) { MemberRefExprBits.IsSuper = isSuper; } SourceLoc getLoc() const { return NameRange.Start; } SourceRange getSourceRange() const { if (Base->isImplicit()) return NameRange; return SourceRange(Base->getStartLoc(), NameRange.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 Expr { protected: explicit DynamicLookupExpr(ExprKind kind) : Expr(kind, /*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 = /// print(x.foo!(17)) // x.foo has type ((i : Int) -> String)? /// \endcode class DynamicMemberRefExpr : public DynamicLookupExpr { Expr *Base; ConcreteDeclRef Member; SourceLoc DotLoc; SourceLoc NameLoc; public: DynamicMemberRefExpr(Expr *base, SourceLoc dotLoc, ConcreteDeclRef member, SourceLoc nameLoc) : DynamicLookupExpr(ExprKind::DynamicMemberRef), Base(base), Member(member), DotLoc(dotLoc), NameLoc(nameLoc) { } /// Retrieve the base of the expression. Expr *getBase() const { return Base; } /// Replace the base of the expression. void setBase(Expr *base) { Base = base; } /// Retrieve the member to which this access refers. ConcreteDeclRef getMember() const { return Member; } /// Retrieve the location of the member name. SourceLoc getNameLoc() const { return NameLoc; } /// Retrieve the location of the '.'. SourceLoc getDotLoc() const { return DotLoc; } SourceLoc getLoc() const { return NameLoc; } SourceRange getSourceRange() const { if (Base->isImplicit()) return SourceRange(NameLoc); return SourceRange(Base->getStartLoc(), NameLoc); } 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 = /// print(x[27]! // x[27] has type String? /// \endcode class DynamicSubscriptExpr : public DynamicLookupExpr { Expr *Base; Expr *Index; ConcreteDeclRef Member; public: DynamicSubscriptExpr(Expr *base, Expr *index, ConcreteDeclRef member) : DynamicLookupExpr(ExprKind::DynamicSubscript), Base(base), Index(index), Member(member) { } /// Retrieve the base of the expression. Expr *getBase() const { return Base; } /// Replace the base of the expression. void setBase(Expr *base) { Base = base; } /// 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; } /// Retrieve the member to which this access refers. ConcreteDeclRef getMember() const { return Member; } SourceLoc getLoc() const { return Index->getStartLoc(); } SourceRange getSourceRange() const { return SourceRange(Base->getStartLoc(), 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 : public Expr { SourceLoc DotLoc; SourceLoc NameLoc; Identifier Name; Expr *Argument; public: UnresolvedMemberExpr(SourceLoc dotLoc, SourceLoc nameLoc, Identifier name, Expr *argument) : Expr(ExprKind::UnresolvedMember, /*Implicit=*/false), DotLoc(dotLoc), NameLoc(nameLoc), Name(name), Argument(argument) { } Identifier getName() const { return Name; } SourceLoc getNameLoc() const { return NameLoc; } SourceLoc getDotLoc() const { return DotLoc; } Expr *getArgument() const { return Argument; } void setArgument(Expr *argument) { Argument = argument; } SourceLoc getLoc() const { return NameLoc; } SourceRange getSourceRange() const; static bool classof(const Expr *E) { return E->getKind() == ExprKind::UnresolvedMember; } }; /// An expression node that does not affect the evaluation of its subexpression. class IdentityExpr : public Expr { Expr *SubExpr; // FIXME: Hack for CollectionExpr::getElements() friend class CollectionExpr; public: IdentityExpr(ExprKind kind, Expr *subExpr, Type ty = Type()) : Expr(kind, /*implicit*/ false, 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; } SourceRange getSourceRange() const { return {getSubExpr()->getStartLoc(), 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; /// \brief Whether we're wrapping a trailing closure expression. /// FIXME: Pack bit into superclass. bool HasTrailingClosure; public: ParenExpr(SourceLoc lploc, Expr *subExpr, SourceLoc rploc, bool hasTrailingClosure, Type ty = Type()) : IdentityExpr(ExprKind::Paren, subExpr, ty), LParenLoc(lploc), RParenLoc(rploc), HasTrailingClosure(hasTrailingClosure) { assert(lploc.isValid() == rploc.isValid() && "Mismatched source location information"); } SourceLoc getLParenLoc() const { return LParenLoc; } SourceLoc getRParenLoc() const { return RParenLoc; } SourceRange getSourceRange() const { // When the locations of the parentheses are invalid, ask our subexpression // for its source range instead. if (LParenLoc.isInvalid()) return getSubExpr()->getSourceRange(); // If we have a trailing closure, our end point is the end of the trailing // closure. if (HasTrailingClosure) return SourceRange(LParenLoc, getSubExpr()->getEndLoc()); return SourceRange(LParenLoc, RParenLoc); } /// \brief Whether this expression has a trailing closure as its argument. bool hasTrailingClosure() const { return 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 : public Expr { SourceLoc LParenLoc; SourceLoc RParenLoc; unsigned NumElements; /// Retrieve the buffer containing the element names. MutableArrayRef getElementNamesBuffer() { if (!hasElementNames()) return { }; return { reinterpret_cast( getElements().data() + getNumElements()), getNumElements() }; } /// Retrieve the buffer containing the element name locations. MutableArrayRef getElementNameLocsBuffer() { if (!hasElementNameLocs()) return { }; return { reinterpret_cast( getElementNamesBuffer().data() + getNumElements()), getNumElements() }; } TupleExpr(SourceLoc LParenLoc, ArrayRef SubExprs, ArrayRef ElementNames, ArrayRef ElementNameLocs, SourceLoc RParenLoc, bool HasTrailingClosure, bool Implicit, Type Ty); public: /// Create a tuple. static TupleExpr *create(ASTContext &ctx, SourceLoc LParenLoc, ArrayRef SubExprs, ArrayRef ElementNames, ArrayRef 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 SubExprs, ArrayRef ElementNames); SourceLoc getLParenLoc() const { return LParenLoc; } SourceLoc getRParenLoc() const { return RParenLoc; } SourceRange getSourceRange() const; /// \brief Whether this expression has a trailing closure as its argument. bool hasTrailingClosure() const { return TupleExprBits.HasTrailingClosure; } /// Retrieve the elements of this tuple. MutableArrayRef getElements() { return { reinterpret_cast(this + 1), getNumElements() }; } /// Retrieve the elements of this tuple. ArrayRef getElements() const { return { reinterpret_cast(this + 1), getNumElements() }; } unsigned getNumElements() const { return 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 TupleExprBits.HasElementNames; } /// Retrieve the element names for a tuple. ArrayRef getElementNames() const { if (!hasElementNames()) return { }; return { reinterpret_cast( getElements().data() + getNumElements()), getNumElements() }; } /// 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 TupleExprBits.HasElementNameLocations; } /// Retrieve the locations of the element names for a tuple. ArrayRef getElementNameLocs() const { if (!hasElementNameLocs()) return { }; return { reinterpret_cast( getElementNames().data() + getNumElements()), getNumElements() }; } /// 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; } }; /// \brief 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 *SubExpr; Expr *SemanticExpr; protected: CollectionExpr(ExprKind Kind, SourceLoc LBracketLoc, Expr *SubExpr, SourceLoc RBracketLoc, Type Ty) : Expr(Kind, /*Implicit=*/false, Ty), LBracketLoc(LBracketLoc), RBracketLoc(RBracketLoc), SubExpr(SubExpr), SemanticExpr(nullptr) { } public: /// Get the ParenExpr or TupleExpr representing the literal contents /// of the container. Expr *getSubExpr() const { return SubExpr; } void setSubExpr(Expr *e) { SubExpr = e; } /// Retrieve the elements stored in the collection. ArrayRef getElements() const; 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; } }; /// \brief An array literal expression [a, b, c]. class ArrayExpr : public CollectionExpr { public: ArrayExpr(SourceLoc LBracketLoc, Expr *SubExpr, SourceLoc RBracketLoc, Type Ty = Type()) : CollectionExpr(ExprKind::Array, LBracketLoc, SubExpr, RBracketLoc, Ty) { } static bool classof(const Expr *e) { return e->getKind() == ExprKind::Array; } }; /// \brief A dictionary literal expression [a : x, b : y, c : z]. class DictionaryExpr : public CollectionExpr { public: DictionaryExpr(SourceLoc LBracketLoc, Expr *SubExpr, SourceLoc RBracketLoc, Type Ty = Type()) : CollectionExpr(ExprKind::Dictionary, LBracketLoc, SubExpr, RBracketLoc, Ty) { } 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 : public Expr { ConcreteDeclRef TheDecl; Expr *Base; Expr *Index; public: SubscriptExpr(Expr *base, Expr *index, ConcreteDeclRef decl = ConcreteDeclRef()) : Expr(ExprKind::Subscript, /*Implicit=*/false, Type()), TheDecl(decl), Base(base), Index(index) { SubscriptExprBits.IsSuper = false; } /// getBase - Retrieve the base of the subscript expression, i.e., the /// value being indexed. Expr *getBase() const { return Base; } void setBase(Expr *E) { Base = E; } /// 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; } /// Determine whether this member reference refers to the /// superclass's property. bool isSuper() const { return SubscriptExprBits.IsSuper; } /// Set whether this member reference refers to the superclass's /// property. void setIsSuper(bool isSuper) { SubscriptExprBits.IsSuper = isSuper; } /// Determine whether subscript operation has a known underlying /// subscript declaration or not. bool hasDecl() const { return static_cast(TheDecl); } /// Retrieve the subscript declaration that this subscripting /// operation refers to. Only valid when \c hasDecl() is true. ConcreteDeclRef getDecl() const { assert(hasDecl() && "No subscript declaration known!"); return TheDecl; } SourceRange getSourceRange() const { return SourceRange(Base->getStartLoc(), Index->getEndLoc()); } static bool classof(const Expr *E) { return E->getKind() == ExprKind::Subscript; } }; /// A member access (foo.bar) on an expression with unresolved type. class UnresolvedDotExpr : public Expr { Expr *SubExpr; SourceLoc DotLoc; SourceLoc NameLoc; Identifier Name; public: UnresolvedDotExpr(Expr *subexpr, SourceLoc dotloc, Identifier name, SourceLoc nameloc, bool Implicit) : Expr(ExprKind::UnresolvedDot, Implicit), SubExpr(subexpr), DotLoc(dotloc), NameLoc(nameloc), Name(name) {} SourceLoc getLoc() const { return NameLoc; } SourceRange getSourceRange() const { if (DotLoc.isInvalid()) return SourceRange(NameLoc, NameLoc); return SourceRange(SubExpr->getStartLoc(), NameLoc); } SourceLoc getDotLoc() const { return DotLoc; } Expr *getBase() const { return SubExpr; } void setBase(Expr *e) { SubExpr = e; } Identifier getName() const { return Name; } SourceLoc getNameLoc() const { return NameLoc; } static bool classof(const Expr *E) { return E->getKind() == ExprKind::UnresolvedDot; } }; /// A selector-style member access (foo.bar:bas:) on an expression with /// unresolved type. class UnresolvedSelectorExpr : public Expr { public: // A selector component. struct ComponentLoc { SourceLoc NameLoc; SourceLoc ColonLoc; }; private: Expr *SubExpr; SourceLoc DotLoc; DeclName Name; MutableArrayRef getComponentsBuf() { return {reinterpret_cast(this+1), Name.getArgumentNames().size() + 1}; } UnresolvedSelectorExpr(Expr *subExpr, SourceLoc dotLoc, DeclName name, ArrayRef components); public: static UnresolvedSelectorExpr *create(ASTContext &C, Expr *subExpr, SourceLoc dotLoc, DeclName name, ArrayRef components); ArrayRef getComponentLocs() const { return {reinterpret_cast(this+1), Name.getArgumentNames().size() + 1}; } SourceLoc getLoc() const { return getComponentLocs().front().NameLoc; } SourceRange getSourceRange() const { return {SubExpr->getStartLoc(), getComponentLocs().back().ColonLoc}; } SourceLoc getDotLoc() const { return DotLoc; } Expr *getBase() const { return SubExpr; } void setBase(Expr *e) { SubExpr = e; } SourceRange getNameRange() const { return {getComponentLocs().front().NameLoc, getComponentLocs().back().ColonLoc}; } DeclName getName() const { return Name; } static bool classof(const Expr *E) { return E->getKind() == ExprKind::UnresolvedSelector; } }; /// ModuleExpr - Reference a module by name. The module being referenced is /// captured in the type of the expression, which is always a ModuleType. class ModuleExpr : public Expr { SourceLoc Loc; public: ModuleExpr(SourceLoc Loc, Type Ty) : Expr(ExprKind::Module, /*Implicit=*/false, Ty), Loc(Loc) {} SourceRange getSourceRange() const { return SourceRange(Loc, Loc); } SourceLoc getLoc() const { return Loc; } static bool classof(const Expr *E) { return E->getKind() == ExprKind::Module; } }; /// TupleElementExpr - Refer to an element of a tuple, /// e.g. "(1,field:2).field". class TupleElementExpr : public Expr { Expr *SubExpr; SourceLoc NameLoc; unsigned FieldNo; SourceLoc DotLoc; public: TupleElementExpr(Expr *SubExpr, SourceLoc DotLoc, unsigned FieldNo, SourceLoc NameLoc, Type Ty) : Expr(ExprKind::TupleElement, /*Implicit=*/false, Ty), SubExpr(SubExpr), NameLoc(NameLoc), FieldNo(FieldNo), DotLoc(DotLoc) {} SourceLoc getLoc() const { return NameLoc; } Expr *getBase() const { return SubExpr; } void setBase(Expr *e) { SubExpr = e; } unsigned getFieldNumber() const { return FieldNo; } SourceLoc getNameLoc() const { return NameLoc; } SourceLoc getDotLoc() const { return DotLoc; } SourceRange getSourceRange() const { return SourceRange(getBase()->getStartLoc(), getNameLoc()); } static bool classof(const Expr *E) { return E->getKind() == ExprKind::TupleElement; } }; /// \brief 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) { BindOptionalExprBits.Depth = depth; assert(BindOptionalExprBits.Depth == depth && "bitfield truncation"); } SourceRange getSourceRange() const { if (QuestionLoc.isInvalid()) return SubExpr->getSourceRange(); return SourceRange(SubExpr->getStartLoc(), QuestionLoc); } SourceLoc getLoc() const { return getQuestionLoc(); } SourceLoc getQuestionLoc() const { return QuestionLoc; } unsigned getDepth() const { return BindOptionalExprBits.Depth; } Expr *getSubExpr() const { return SubExpr; } void setSubExpr(Expr *expr) { SubExpr = expr; } static bool classof(const Expr *E) { return E->getKind() == ExprKind::BindOptional; } }; /// \brief 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) {} SourceRange getSourceRange() const { return SubExpr->getSourceRange(); } SourceLoc getLoc() const { return SubExpr->getLoc(); } Expr *getSubExpr() const { return SubExpr; } void setSubExpr(Expr *expr) { SubExpr = expr; } static bool classof(const Expr *E) { return E->getKind() == ExprKind::OptionalEvaluation; } }; /// \brief 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) : Expr(ExprKind::ForceValue, /*Implicit=*/exclaimLoc.isInvalid(), Type()), SubExpr(subExpr), ExclaimLoc(exclaimLoc) {} SourceRange getSourceRange() const { if (ExclaimLoc.isInvalid()) return SubExpr->getSourceRange(); return SourceRange(SubExpr->getStartLoc(), ExclaimLoc); } SourceLoc getLoc() const { return getExclaimLoc(); } SourceLoc getExclaimLoc() const { return ExclaimLoc; } Expr *getSubExpr() const { return SubExpr; } void setSubExpr(Expr *expr) { SubExpr = expr; } static bool classof(const Expr *E) { return E->getKind() == ExprKind::ForceValue; } }; /// \brief 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 in /// narrow circumstances where we need a way to refer to the dynamic /// type, i.e., when calling a method on a protocol that returns /// Self. 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) : Expr(ExprKind::OpenExistential, /*Implicit=*/ true, subExpr->getType()), ExistentialValue(existentialValue), OpaqueValue(opaqueValue), SubExpr(subExpr) { } SourceRange getSourceRange() const { return SubExpr->getSourceRange(); } SourceLoc getLoc() const { return SubExpr->getLoc(); } /// 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; } /// 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. ArchetypeType *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: SourceRange getSourceRange() const { return SubExpr->getSourceRange(); } 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_ImplicitConversionExpr && E->getKind() <= ExprKind::Last_ImplicitConversionExpr; } }; /// 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 an lvalue to an lvalue of a different type using a pair of /// conversion functions. class LValueConversionExpr : public ImplicitConversionExpr { // The conversion function that converts from the original type to the // converted type. Expr *FromConversionFn; // The conversion function that converts back to the original type from the // converted type. Expr *ToConversionFn; public: LValueConversionExpr(Expr *SubExpr, Type Ty, Expr *FromConversionFn, Expr *ToConversionFn) : ImplicitConversionExpr(ExprKind::LValueConversion, SubExpr, Ty), FromConversionFn(FromConversionFn), ToConversionFn(ToConversionFn) {} /// Get the expression that produces the function that converts from the /// original lvalue type to the converted type. Expr *getFromConversionFn() const { return FromConversionFn; } void setFromConversionFn(Expr *e) { FromConversionFn = e; } /// Get the expression that produces the function that converts back to the /// original lvalue type from the converted type. Expr *getToConversionFn() const { return ToConversionFn; } void setToConversionFn(Expr *e) { ToConversionFn = e; } static bool classof(const Expr *E) { return E->getKind() == ExprKind::LValueConversion; } }; /// Convert the address of an lvalue to a raw pointer. class LValueToPointerExpr : public ImplicitConversionExpr { Type AbstractionPattern; public: LValueToPointerExpr(Expr *subExpr, Type ty, Type abstractionTy) : ImplicitConversionExpr(ExprKind::LValueToPointer, subExpr, ty), AbstractionPattern(abstractionTy) {} /// Get the declared type of the type for which we are performing this /// conversion. This defines the abstraction level at which the lvalue should /// be emitted before taking its address. Type getAbstractionPatternType() const { return AbstractionPattern; } static bool classof(const Expr *E) { return E->getKind() == ExprKind::LValueToPointer; } }; /// TupleShuffleExpr - This represents a permutation of a tuple value to a new /// tuple type. The expression's type is known to be a tuple type and the /// subexpression is known to have a tuple type as well. class TupleShuffleExpr : public ImplicitConversionExpr { public: enum : int { /// The element mapping value indicating that a field of the destination /// tuple should be default-initialized. DefaultInitialize = -1, /// The element mapping value signaling the first variadic field. FirstVariadic = -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 }; private: /// 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. ArrayRef ElementMapping; /// If we're doing a varargs shuffle, this is the function to build the /// destination slice type. Expr *InjectionFn; /// If there are any default arguments, the owning function /// declaration. ValueDecl *DefaultArgsOwner; MutableArrayRef CallerDefaultArgs; public: TupleShuffleExpr(Expr *subExpr, ArrayRef elementMapping, ValueDecl *defaultArgsOwner, MutableArrayRef CallerDefaultArgs, Type ty) : ImplicitConversionExpr(ExprKind::TupleShuffle, subExpr, ty), ElementMapping(elementMapping), InjectionFn(nullptr), DefaultArgsOwner(defaultArgsOwner), CallerDefaultArgs(CallerDefaultArgs) { } ArrayRef getElementMapping() const { return ElementMapping; } /// Set the injection function expression to use. void setVarargsInjectionFunction(Expr *fn) { InjectionFn = fn; } Expr *getVarargsInjectionFunction() const { assert(InjectionFn != nullptr); return InjectionFn; } Expr *getVarargsInjectionFunctionOrNull() const { return InjectionFn; } /// Retrieve the owner of the default arguments. ValueDecl *getDefaultArgsOwner() const { return DefaultArgsOwner; } /// Retrieve the caller-defaulted arguments. ArrayRef getCallerDefaultArgs() const { return CallerDefaultArgs; } /// Retrieve the caller-defaulted arguments. MutableArrayRef getCallerDefaultArgs() { return CallerDefaultArgs; } 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; } }; /// 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; } }; /// 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; } }; // ArrayUpcastConversionExpr - Convert an Array to an Array, where // U is a subtype of T. class ArrayUpcastConversionExpr : public ImplicitConversionExpr { public: ArrayUpcastConversionExpr(Expr *subExpr, Type type) : ImplicitConversionExpr(ExprKind::ArrayUpcastConversion, subExpr, type) {} static bool classof(const Expr *E) { return E->getKind() == ExprKind::ArrayUpcastConversion; } }; // ArrayBridgedConversionExpr - Convert an Array to an Array, where // T is bridged to U. class ArrayBridgedConversionExpr : public ImplicitConversionExpr { public: /// Keep track of whether or not the type being bridged to conforms to the /// _ConditionallyBridgedToObjectiveC protocol. bool isConditionallyBridged = false; ArrayBridgedConversionExpr(Expr *subExpr, Type type) : ImplicitConversionExpr(ExprKind::ArrayBridgedConversion, subExpr, type) {} static bool classof(const Expr *E) { return E->getKind() == ExprKind::ArrayBridgedConversion; } }; /// AnyErasureExpr - An abstract class for implicit conversions that /// erase a type into an existential in some way. /// /// 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 AnyErasureExpr : public ImplicitConversionExpr { ArrayRef Conformances; protected: AnyErasureExpr(ExprKind kind, Expr *subExpr, Type type, ArrayRef conformances) : ImplicitConversionExpr(kind, subExpr, type), Conformances(conformances) {} public: /// \brief 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 getConformances() const { return Conformances; } static bool classof(const Expr *E) { return E->getKind() >= ExprKind::First_AnyErasureExpr && E->getKind() <= ExprKind::Last_AnyErasureExpr; } }; /// ErasureExpr - Perform type erasure by converting a value to existential /// type. For example: /// /// \code /// protocol Printable { /// func print() /// } /// /// struct Book { /// func print() { ... } /// } /// /// var printable : Printable = Book() // erases type /// \endcode /// /// The result type is always a existential value (i.e. not an /// existential metatype). class ErasureExpr : public AnyErasureExpr { public: ErasureExpr(Expr *subExpr, Type ty, ArrayRef conformances) : AnyErasureExpr(ExprKind::Erasure, subExpr, ty, conformances) {} static bool classof(const Expr *E) { return E->getKind() == ExprKind::Erasure; } }; /// MetatypeErasureExpr - Perform type erasure by converting a /// metatype to an existential metatype type. For example: /// /// \code /// protocol Singleton { /// static func getSingleton() -> Self /// } /// /// class Book : Singleton { /// class func getSingleton() -> Self { ... } /// } /// /// var singletonType : Singleton.Type = Book.self // erases type /// \endcode /// /// The type is always an existential metatype; the operand may be a /// concrete or existential metatype. class MetatypeErasureExpr : public AnyErasureExpr { public: MetatypeErasureExpr(Expr *subExpr, Type ty, ArrayRef conformances) : AnyErasureExpr(ExprKind::MetatypeErasure, subExpr, ty, conformances) {} static bool classof(const Expr *E) { return E->getKind() == ExprKind::MetatypeErasure; } }; /// UnresolvedSpecializeExpr - Represents an explicit specialization using /// a type parameter list (e.g. "Vector") that has not been resolved. class UnresolvedSpecializeExpr : public Expr { Expr *SubExpr; SourceLoc LAngleLoc; SourceLoc RAngleLoc; MutableArrayRef UnresolvedParams; public: UnresolvedSpecializeExpr(Expr *SubExpr, SourceLoc LAngleLoc, MutableArrayRef UnresolvedParams, SourceLoc RAngleLoc) : Expr(ExprKind::UnresolvedSpecialize, /*Implicit=*/false), SubExpr(SubExpr), LAngleLoc(LAngleLoc), RAngleLoc(RAngleLoc), UnresolvedParams(UnresolvedParams) { } Expr *getSubExpr() const { return SubExpr; } void setSubExpr(Expr *e) { SubExpr = e; } /// \brief Retrieve the list of type parameters. These parameters have not yet /// been bound to archetypes of the entity to be specialized. ArrayRef getUnresolvedParams() const { return UnresolvedParams; } MutableArrayRef getUnresolvedParams() { return UnresolvedParams; } SourceLoc getLoc() const { return LAngleLoc; } SourceLoc getLAngleLoc() const { return LAngleLoc; } SourceLoc getRAngleLoc() const { return RAngleLoc; } SourceRange getSourceRange() const { return SourceRange(SubExpr->getStartLoc(), RAngleLoc); } static bool classof(const Expr *E) { return E->getKind() == ExprKind::UnresolvedSpecialize; } }; /// \brief 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; } }; /// \brief 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; } }; /// ScalarToTupleExpr - Convert a scalar to tuple type. class ScalarToTupleExpr : public ImplicitConversionExpr { public: /// Describes an element of the destination tuple, which can be the /// caller-side default argument expression, the declaration from which the /// callee-side default argument should be produced, or null to indicate the /// 'hole' where the scalar expression should be placed. typedef llvm::PointerUnion Element; private: /// If we're doing a varargs shuffle, this is the function to build the /// destination slice type. Expr *InjectionFn; /// The elements of the destination tuple. MutableArrayRef Elements; public: ScalarToTupleExpr(Expr *subExpr, Type type, MutableArrayRef elements, Expr *InjectionFn = nullptr) : ImplicitConversionExpr(ExprKind::ScalarToTuple, subExpr, type), InjectionFn(InjectionFn), Elements(elements) {} /// Retrieve the index of the scalar field within the destination tuple. unsigned getScalarField() const; /// Retrieve the expression that refers to the injection function. Expr *getVarargsInjectionFunction() { return InjectionFn; } /// Retrieve the elements of the destination tuple. MutableArrayRef getElements() { return Elements; } ArrayRef getElements() const { return Elements; } static bool classof(const Expr *E) { return E->getKind() == ExprKind::ScalarToTuple; } }; /// 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 type, bool isImplicit = false) : Expr(ExprKind::InOut, isImplicit, type), SubExpr(subExpr), OperLoc(operLoc) {} SourceRange getSourceRange() const { return SourceRange(OperLoc, 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; } }; /// 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 : public Expr { unsigned NumElements; Expr **getSubExprs() { return reinterpret_cast(this + 1); } Expr * const *getSubExprs() const { return const_cast(this)->getSubExprs(); } SequenceExpr(ArrayRef elements) : Expr(ExprKind::Sequence, /*Implicit=*/false), NumElements(elements.size()) { assert(NumElements > 0 && "zero-length sequence!"); memcpy(getSubExprs(), elements.data(), elements.size() * sizeof(Expr*)); } public: static SequenceExpr *create(ASTContext &ctx, ArrayRef elements); SourceRange getSourceRange() const { return SourceRange(getElements()[0]->getStartLoc(), getElements()[getNumElements() - 1]->getEndLoc()); } unsigned getNumElements() const { return NumElements; } MutableArrayRef getElements() { return MutableArrayRef(getSubExprs(), NumElements); } ArrayRef getElements() const { return ArrayRef(getSubExprs(), NumElements); } Expr *getElement(unsigned i) const { assert(i < NumElements); return getSubExprs()[i]; } void setElement(unsigned i, Expr *e) { assert(i < NumElements); getSubExprs()[i] = e; } // Implement isa/cast/dyncast/etc. static bool classof(const Expr *E) { return E->getKind() == ExprKind::Sequence; } }; /// \brief A base class for closure expressions. class AbstractClosureExpr : public Expr, public DeclContext { CaptureInfo Captures; /// \brief The set of parameters. Pattern *ParamPattern; public: AbstractClosureExpr(ExprKind Kind, Type FnType, bool Implicit, unsigned Discriminator, DeclContext *Parent) : Expr(Kind, Implicit, FnType), DeclContext(DeclContextKind::AbstractClosureExpr, Parent), ParamPattern(nullptr) { AbstractClosureExprBits.Discriminator = Discriminator; } CaptureInfo &getCaptureInfo() { return Captures; } const CaptureInfo &getCaptureInfo() const { return Captures; } /// \brief Retrieve the parameters of this closure. Pattern *getParams() { return ParamPattern; } const Pattern *getParams() const { return ParamPattern; } void setParams(Pattern *P); /// 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 AbstractClosureExprBits.Discriminator; } void setDiscriminator(unsigned discriminator) { assert(getDiscriminator() == InvalidDiscriminator); assert(discriminator != InvalidDiscriminator); AbstractClosureExprBits.Discriminator = discriminator; } enum : unsigned { InvalidDiscriminator = decltype(AbstractClosureExprBits)::InvalidDiscriminator }; ArrayRef getParamPatterns() { return ParamPattern; } ArrayRef getParamPatterns() const { return ParamPattern; } /// \brief Retrieve the result type of this closure. Type getResultType() 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; }; /// Instances of this structure represent elements of the capture list that can /// optionally occur in a capture expression. struct CaptureListEntry { enum KindTy { Strong, Weak, Unowned, UnownedSafe, UnownedUnsafe } Kind; SourceLoc Loc; Identifier Name; Expr *Init; CaptureListEntry(KindTy Kind, SourceLoc Loc, Identifier Name, Expr *Init) : Kind(Kind), Loc(Loc), Name(Name), Init(Init) { } }; /// \brief 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 { ArrayRef CaptureList; /// \brief The location of the '->' denoting an explicit return type, /// if present. SourceLoc ArrowLoc; /// \brief The explicitly-specified result type. TypeLoc ExplicitResultType; /// \brief The body of the closure, along with a bit indicating whether it /// was originally just a single expression. llvm::PointerIntPair Body; public: ClosureExpr(ArrayRef captureList, Pattern *params, SourceLoc arrowLoc, TypeLoc explicitResultType, unsigned discriminator, DeclContext *parent) : AbstractClosureExpr(ExprKind::Closure, Type(), /*Implicit=*/false, discriminator, parent), CaptureList(captureList), ArrowLoc(arrowLoc), ExplicitResultType(explicitResultType), Body(nullptr) { setParams(params); ClosureExprBits.HasAnonymousClosureVars = false; } SourceRange getSourceRange() const; SourceLoc getLoc() const; BraceStmt *getBody() const { return Body.getPointer(); } void setBody(BraceStmt *S, bool isSingleExpression) { Body.setPointer(S); Body.setInt(isSingleExpression); } // Expose this to users. using DeclContext::setParent; ArrayRef getCaptureList() { return CaptureList; } /// \brief Determine whether the parameters of this closure are actually /// anonymous closure variables. bool hasAnonymousClosureVars() const { return ClosureExprBits.HasAnonymousClosureVars; } /// \brief Set the parameters of this closure along with a flag indicating /// whether these parameters are actually anonymous closure variables. void setHasAnonymousClosureVars() { ClosureExprBits.HasAnonymousClosureVars = true; } /// \brief Determine whether this closure expression has an /// explicitly-specified result type. bool hasExplicitResultType() const { return ArrowLoc.isValid(); } /// \brief Retrieve the location of the \c '->' for closures with an /// explicit result type. SourceLoc getArrowLoc() const { assert(hasExplicitResultType() && "No arrow location"); return ArrowLoc; } /// \brief Retrieve the explicit result type location information. TypeLoc &getExplicitResultTypeLoc() { assert(hasExplicitResultType() && "No explicit result type"); return ExplicitResultType; } /// \brief 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 /// /// But not for empty closures nor bool hasSingleExpressionBody() const { return Body.getInt(); } /// \brief Retrieve the body for closure that has a single expression for /// its body. /// /// Only valid when \c hasSingleExpressionBody() is true. Expr *getSingleExpressionBody() const; /// \brief 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); static bool classof(const Expr *E) { return E->getKind() == ExprKind::Closure; } }; /// \brief This is a closure of the contained subexpression that is formed /// when an scalar expression is converted to @auto_closure function type. /// For example: /// \code /// var x : @auto_closure () -> int = 4 /// \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; BraceStmt *getBody() const { return Body; } void setBody(Expr *E); // Expose this to users. using DeclContext::setParent; /// Returns the body of the auto_closure as an \c Expr. /// /// The body of an auto_closure 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; } }; /// The allocation of an array. Allocates and constructs /// the array, then injects that into the corresponding slice type. class NewArrayExpr : public Expr { public: struct Bound { Expr *Value; SourceRange Brackets; Bound() = default; Bound(Expr *value, SourceRange brackets) : Value(value), Brackets(brackets) {} }; private: TypeLoc ElementTyAsWritten; Type ElementTy; unsigned NumBounds; SourceLoc NewLoc; Expr *InjectionFn; Expr *ConstructionFn; NewArrayExpr(SourceLoc newLoc, TypeLoc elementTy, unsigned numBounds, Expr *constructionFn) : Expr(ExprKind::NewArray, /*Implicit=*/false, Type()), ElementTyAsWritten(elementTy), NumBounds(numBounds), NewLoc(newLoc), InjectionFn(nullptr), ConstructionFn(constructionFn) {} Bound *getBoundsBuffer() { return reinterpret_cast(this + 1); } const Bound *getBoundsBuffer() const { return reinterpret_cast(this + 1); } public: static NewArrayExpr *create(ASTContext &Context, SourceLoc newLoc, TypeLoc elementTy, ArrayRef bounds, Expr *constructionFn); unsigned getNumBounds() const { return NumBounds; } MutableArrayRef getBounds() { return MutableArrayRef(getBoundsBuffer(), getNumBounds()); } ArrayRef getBounds() const { return ArrayRef(getBoundsBuffer(), getNumBounds()); } /// Return the location of the 'new' keyword. SourceLoc getNewLoc() const { return NewLoc; } SourceRange getSourceRange() const { auto endLoc = ConstructionFn && !ConstructionFn->isImplicit() ? ConstructionFn->getEndLoc() : getBounds().back().Brackets.End; return SourceRange(NewLoc, endLoc); } SourceLoc getLoc() const { return NewLoc; } /// Set the injection function expression to use to form the array value. void setInjectionFunction(Expr *fn) { InjectionFn = fn; } Expr *getInjectionFunction() const { assert(InjectionFn != nullptr); return InjectionFn; } bool hasInjectionFunction() const { return InjectionFn != nullptr; } /// Set the construction function expression to use to initialize the array /// elements. This should have function type (IndexType) -> ElementType. void setConstructionFunction(Expr *fn) { ConstructionFn = fn; } Expr *getConstructionFunction() const { assert(ConstructionFn != nullptr); return ConstructionFn; } bool hasConstructionFunction() const { return ConstructionFn != nullptr; } bool hasElementType() const { return !ElementTy.isNull(); } Type getElementType() const { assert(ElementTy && "Element type not yet computed!"); return ElementTy; } void setElementType(Type T) { ElementTy = T; } TypeLoc &getElementTypeLoc() { return ElementTyAsWritten; } static bool classof(const Expr *E) { return E->getKind() == ExprKind::NewArray; } }; /// DynamicTypeExpr - "base.dynamicType" - Produces a metatype value. /// /// The metatype value can comes from a evaluating an expression and then /// getting its metatype. class DynamicTypeExpr : public Expr { Expr *Base; SourceLoc MetatypeLoc; public: explicit DynamicTypeExpr(Expr *Base, SourceLoc MetatypeLoc, Type Ty) : Expr(ExprKind::DynamicType, /*Implicit=*/false, Ty), Base(Base), MetatypeLoc(MetatypeLoc) { } Expr *getBase() const { return Base; } void setBase(Expr *base) { Base = base; } SourceLoc getLoc() const { return MetatypeLoc; } SourceLoc getMetatypeLoc() const { return MetatypeLoc; } SourceRange getSourceRange() const; 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; bool UniquelyReferenced = false; public: explicit OpaqueValueExpr(SourceLoc Loc, Type Ty) : Expr(ExprKind::OpaqueValue, /*Implicit=*/true, Ty), Loc(Loc) { } /// Determine whether this opaque value is referenced at only one point in /// the AST. /// /// Opaque values referenced at only one place in the AST can be referenced /// more efficiently, be eliminating extra retain/release traffic. bool isUniquelyReferenced() const { return UniquelyReferenced; } void setUniquelyReferenced(bool uniqueRef) { UniquelyReferenced = uniqueRef; } 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 ArgAndIsSuper; 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"); } public: /// Signifies whether or not this is an application of a potentially delayed, /// globally scoped operator. bool IsGlobalDelayedOperatorApply = false; Expr *getFn() const { return Fn; } void setFn(Expr *e) { Fn = e; } Expr *getArg() const { return ArgAndIsSuper.getPointer(); } void setArg(Expr *e) { assert((getKind() != ExprKind::Binary || isa(e)) && "BinaryExprs must have a TupleExpr as the argument"); ArgAndIsSuper = {e, ArgAndIsSuper.getInt()}; } bool isSuper() const { return ArgAndIsSuper.getInt(); } void setIsSuper(bool super) { ArgAndIsSuper = {ArgAndIsSuper.getPointer(), super}; } ValueDecl *getCalledValue() 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 : public ApplyExpr { public: CallExpr(Expr *fn, Expr *arg, bool Implicit, Type ty = Type()) : ApplyExpr(ExprKind::Call, fn, arg, Implicit, ty) {} SourceRange getSourceRange() const { return SourceRange(getFn()->getStartLoc(), getArg()->getEndLoc()); } SourceLoc getLoc() const { return getFn()->getLoc(); } 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(); } SourceRange getSourceRange() const { return SourceRange(getFn()->getStartLoc(), getArg()->getEndLoc()); } static bool classof(const Expr *E) { return E->getKind() == ExprKind::PrefixUnary; } }; /// PostfixUnaryExpr - Prefix 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(); } SourceRange getSourceRange() const { return SourceRange(getArg()->getStartLoc(), 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(); } TupleExpr *getArg() const { return cast(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(); } SourceRange getSourceRange() const { return SourceRange(getStartLoc(), 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(); } SourceRange getSourceRange() const { return SourceRange(getStartLoc(), 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) : Expr(ExprKind::DotSyntaxBaseIgnored, /*Implicit=*/false, RHS->getType()), 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(); } SourceRange getSourceRange() const { return SourceRange(getStartLoc(), RHS->getEndLoc()); } static bool classof(const Expr *E) { return E->getKind() == ExprKind::DotSyntaxBaseIgnored; } }; /// Indicates that the enclosed apply expression is an inout conversion. /// /// Unlike a normal call, calls inside the inout conversion do not get their /// own writeback scope, but instead extend the writeback chain for the /// surrounding call. This ensures that in an expression like: /// foo(&a) /// 'a' is not written back to until the end of 'foo', even if passing /// '&a' to foo involves an inout conversion. class InOutConversionExpr : public Expr { SourceLoc OperLoc; Expr *SubExpr; public: InOutConversionExpr(SourceLoc OperLoc, Expr *SubExpr, bool Implicit = false) : Expr(ExprKind::InOutConversion, Implicit, SubExpr->getType()), OperLoc(OperLoc), SubExpr(SubExpr) {} Expr *getSubExpr() const { return SubExpr; } void setSubExpr(Expr *apply) { SubExpr = apply; } /// Location of the '&' operator for the inout expression. SourceLoc getLoc() const { return OperLoc; } SourceRange getSourceRange() const { return {OperLoc, SubExpr->getSourceRange().End}; } static bool classof(const Expr *E) { return E->getKind() == ExprKind::InOutConversion; } }; /// \brief 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, ForceLoc; 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(); } SourceRange getSourceRange() const { if (CastTy.getSourceRange().isInvalid()) return SubExpr->getSourceRange(); auto startLoc = SubExpr ? SubExpr->getStartLoc() : AsLoc; auto endLoc = ForceLoc.isValid() ? ForceLoc : CastTy.getSourceRange().End; return {startLoc, endLoc}; } /// True if the node has been processed by SequenceExpr folding. bool isFolded() const { return SubExpr; } /// Location of a trailing unparenthesizeded postfix '!' that may have /// followed this cast. SourceLoc getForceLoc() const { return ForceLoc; } void setForceLoc(SourceLoc loc) { ForceLoc = loc; } 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); /// \brief 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) { CheckedCastExprBits.CastKind = unsigned(CheckedCastKind::Unresolved); } /// Return the semantic kind of cast performed. CheckedCastKind getCastKind() const { return CheckedCastKind(CheckedCastExprBits.CastKind); } void setCastKind(CheckedCastKind kind) { CheckedCastExprBits.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; } }; /// \brief 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 { public: ConditionalCheckedCastExpr(Expr *sub, SourceLoc asLoc, TypeLoc type) : CheckedCastExpr(ExprKind::ConditionalCheckedCast, sub, asLoc, type, type.getType()) { } ConditionalCheckedCastExpr(SourceLoc asLoc, TypeLoc type) : ConditionalCheckedCastExpr(nullptr, asLoc, type) {} static bool classof(const Expr *E) { return E->getKind() == ExprKind::ConditionalCheckedCast; } }; /// \brief 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 IsaExpr : public CheckedCastExpr { public: IsaExpr(Expr *sub, SourceLoc isLoc, TypeLoc type) : CheckedCastExpr(ExprKind::Isa, sub, isLoc, type, Type()) {} IsaExpr(SourceLoc isLoc, TypeLoc type) : IsaExpr(nullptr, isLoc, type) {} static bool classof(const Expr *E) { return E->getKind() == ExprKind::Isa; } }; /// \brief 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 { public: CoerceExpr(Expr *sub, SourceLoc asLoc, TypeLoc type) : ExplicitCastExpr(ExprKind::Coerce, sub, asLoc, type, type.getType()) { } static bool classof(const Expr *E) { return E->getKind() == ExprKind::Coerce; } }; /// \brief 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); SourceLoc getLoc() const { return SubExpr->getLoc(); } SourceRange getSourceRange() const { return SubExpr->getSourceRange(); } VarDecl *getSelf() const { return Self; } Expr *getSubExpr() const { return SubExpr; } void setSubExpr(Expr *Sub) { SubExpr = Sub; } static bool classof(const Expr *E) { return E->getKind() == ExprKind::RebindSelfInConstructor; } }; /// \brief 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; } SourceRange getSourceRange() const { if (isFolded()) return {CondExpr->getStartLoc(), ElseExpr->getEndLoc()}; return {QuestionLoc, 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; } }; /// 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 { return EqualLoc; } SourceRange getSourceRange() const; /// 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; } }; /// \brief An expression that describes the use of a default value, which may /// come from the default argument of a function type or member initializer. /// /// This expression is synthesized by type checking and cannot be written /// directly by the user. class DefaultValueExpr : public Expr { Expr *subExpr; public: explicit DefaultValueExpr(Expr *subExpr) : Expr(ExprKind::DefaultValue, /*Implicit=*/true, subExpr->getType()), subExpr(subExpr) { } Expr *getSubExpr() const { return subExpr; } void setSubExpr(Expr *sub) { subExpr = sub; } SourceRange getSourceRange() const { return SourceRange(); } static bool classof(const Expr *E) { return E->getKind() == ExprKind::DefaultValue; } }; /// \brief 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; } SourceLoc getLoc() const; SourceRange getSourceRange() const; static bool classof(const Expr *E) { return E->getKind() == ExprKind::UnresolvedPattern; } }; } // end namespace swift #endif