blob: d5e43bef41fced1caf49106fb8d3d85f1df25a14 [file] [log] [blame]
//===--- Expr.h - Swift Language Expression ASTs ----------------*- C++ -*-===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2018 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See https://swift.org/LICENSE.txt for license information
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//
//
// This file defines the Expr class and subclasses.
//
//===----------------------------------------------------------------------===//
#ifndef SWIFT_AST_EXPR_H
#define SWIFT_AST_EXPR_H
#include "swift/AST/CaptureInfo.h"
#include "swift/AST/ConcreteDeclRef.h"
#include "swift/AST/DeclContext.h"
#include "swift/AST/DeclNameLoc.h"
#include "swift/AST/FunctionRefKind.h"
#include "swift/AST/ProtocolConformanceRef.h"
#include "swift/AST/TrailingCallArguments.h"
#include "swift/AST/TypeAlignments.h"
#include "swift/AST/Availability.h"
#include "swift/Basic/Debug.h"
#include "swift/Basic/InlineBitfield.h"
#include "llvm/Support/TrailingObjects.h"
#include <utility>
namespace llvm {
struct fltSemantics;
}
namespace swift {
enum class AccessKind : unsigned char;
class ArchetypeType;
class ASTContext;
class AvailabilitySpec;
class IdentTypeRepr;
class Type;
class TypeRepr;
class ValueDecl;
class Decl;
class DeclRefExpr;
class OpenedArchetypeType;
class ParamDecl;
class Pattern;
class SubscriptDecl;
class Stmt;
class BraceStmt;
class ASTWalker;
class Initializer;
class VarDecl;
class OpaqueValueExpr;
class FuncDecl;
class ConstructorDecl;
class TypeDecl;
class PatternBindingDecl;
class ParameterList;
class EnumElementDecl;
class CallExpr;
class KeyPathExpr;
class CaptureListExpr;
struct TrailingClosure {
Identifier Label;
SourceLoc LabelLoc;
Expr *ClosureExpr;
TrailingClosure(Expr *closure)
: TrailingClosure(Identifier(), SourceLoc(), closure) {}
TrailingClosure(Identifier label, SourceLoc labelLoc, Expr *closure)
: Label(label), LabelLoc(labelLoc), ClosureExpr(closure) {}
};
enum class ExprKind : uint8_t {
#define EXPR(Id, Parent) Id,
#define LAST_EXPR(Id) Last_Expr = Id,
#define EXPR_RANGE(Id, FirstId, LastId) \
First_##Id##Expr = FirstId, Last_##Id##Expr = LastId,
#include "swift/AST/ExprNodes.def"
};
enum : unsigned { NumExprKindBits =
countBitsUsed(static_cast<unsigned>(ExprKind::Last_Expr)) };
/// Discriminates certain kinds of checked cast that have specialized diagnostic
/// and/or code generation peephole behavior.
///
/// This enumeration should not have any semantic effect on the behavior of a
/// well-typed program, since the runtime can perform all casts that are
/// statically accepted.
enum class CheckedCastKind : unsigned {
/// The kind has not been determined yet.
Unresolved,
/// Valid resolved kinds start here.
First_Resolved,
/// The requested cast is an implicit conversion, so this is a coercion.
Coercion = First_Resolved,
/// A checked cast with no known specific behavior.
ValueCast,
// A downcast from an array type to another array type.
ArrayDowncast,
// A downcast from a dictionary type to another dictionary type.
DictionaryDowncast,
// A downcast from a set type to another set type.
SetDowncast,
/// A bridging conversion that always succeeds.
BridgingCoercion,
Last_CheckedCastKind = BridgingCoercion,
};
/// What are the high-level semantics of this access?
enum class AccessSemantics : uint8_t {
/// On a storage reference, this is a direct access to the underlying
/// physical storage, bypassing any observers. The declaration must be
/// a variable with storage.
///
/// On a function reference, this is a non-polymorphic access to a
/// particular implementation.
DirectToStorage,
/// On a storage reference, this is a direct access to the concrete
/// implementation of this storage, bypassing any possibility of override.
DirectToImplementation,
/// This is an ordinary access to a declaration, using whatever
/// polymorphism is expected.
Ordinary,
};
/// Expr - Base class for all expressions in swift.
class alignas(8) Expr {
Expr(const Expr&) = delete;
void operator=(const Expr&) = delete;
protected:
union { uint64_t OpaqueBits;
SWIFT_INLINE_BITFIELD_BASE(Expr, bitmax(NumExprKindBits,8)+1,
/// The subclass of Expr that this is.
Kind : bitmax(NumExprKindBits,8),
/// Whether the Expr represents something directly written in source or
/// it was implicitly generated by the type-checker.
Implicit : 1
);
SWIFT_INLINE_BITFIELD_FULL(CollectionExpr, Expr, 64-NumExprBits,
/// True if the type of this collection expr was inferred by the collection
/// fallback type, like [Any].
IsTypeDefaulted : 1,
/// Number of comma source locations.
NumCommas : 32 - 1 - NumExprBits,
/// Number of entries in the collection. If this is a DictionaryExpr,
/// each entry is a Tuple with the key and value pair.
NumSubExprs : 32
);
SWIFT_INLINE_BITFIELD_EMPTY(LiteralExpr, Expr);
SWIFT_INLINE_BITFIELD_EMPTY(IdentityExpr, Expr);
SWIFT_INLINE_BITFIELD(LookupExpr, Expr, 1,
IsSuper : 1
);
SWIFT_INLINE_BITFIELD_EMPTY(DynamicLookupExpr, LookupExpr);
SWIFT_INLINE_BITFIELD(ParenExpr, IdentityExpr, 1,
/// Whether we're wrapping a trailing closure expression.
HasTrailingClosure : 1
);
SWIFT_INLINE_BITFIELD(NumberLiteralExpr, LiteralExpr, 1+1,
IsNegative : 1,
IsExplicitConversion : 1
);
SWIFT_INLINE_BITFIELD(StringLiteralExpr, LiteralExpr, 3+1+1,
Encoding : 3,
IsSingleUnicodeScalar : 1,
IsSingleExtendedGraphemeCluster : 1
);
SWIFT_INLINE_BITFIELD_FULL(InterpolatedStringLiteralExpr, LiteralExpr, 32+20,
: NumPadBits,
InterpolationCount : 20,
LiteralCapacity : 32
);
SWIFT_INLINE_BITFIELD(DeclRefExpr, Expr, 2+2,
Semantics : 2, // an AccessSemantics
FunctionRefKind : 2
);
SWIFT_INLINE_BITFIELD(UnresolvedDeclRefExpr, Expr, 2+2,
DeclRefKind : 2,
FunctionRefKind : 2
);
SWIFT_INLINE_BITFIELD(MemberRefExpr, LookupExpr, 2,
Semantics : 2 // an AccessSemantics
);
SWIFT_INLINE_BITFIELD_FULL(TupleElementExpr, Expr, 32,
: NumPadBits,
FieldNo : 32
);
SWIFT_INLINE_BITFIELD_FULL(TupleExpr, Expr, 1+1+32,
/// Whether this tuple has any labels.
HasElementNames : 1,
/// Whether this tuple has label locations.
HasElementNameLocations : 1,
: NumPadBits,
NumElements : 32
);
SWIFT_INLINE_BITFIELD(UnresolvedDotExpr, Expr, 2,
FunctionRefKind : 2
);
SWIFT_INLINE_BITFIELD_FULL(SubscriptExpr, LookupExpr, 2+1+1+16,
Semantics : 2, // an AccessSemantics
/// Whether the SubscriptExpr also has source locations for the argument
/// label.
HasArgLabelLocs : 1,
/// Whether the last argument is a trailing closure.
HasTrailingClosure : 1,
: NumPadBits,
/// # of argument labels stored after the SubscriptExpr.
NumArgLabels : 16
);
SWIFT_INLINE_BITFIELD_FULL(DynamicSubscriptExpr, DynamicLookupExpr, 1+1+16,
/// Whether the DynamicSubscriptExpr also has source locations for the
/// argument label.
HasArgLabelLocs : 1,
/// Whether the last argument is a trailing closure.
HasTrailingClosure : 1,
: NumPadBits,
/// # of argument labels stored after the DynamicSubscriptExpr.
NumArgLabels : 16
);
SWIFT_INLINE_BITFIELD_FULL(UnresolvedMemberExpr, Expr, 2,
FunctionRefKind : 2
);
SWIFT_INLINE_BITFIELD(OverloadSetRefExpr, Expr, 2,
FunctionRefKind : 2
);
SWIFT_INLINE_BITFIELD(BooleanLiteralExpr, LiteralExpr, 1,
Value : 1
);
SWIFT_INLINE_BITFIELD(MagicIdentifierLiteralExpr, LiteralExpr, 3+1,
Kind : 3,
StringEncoding : 1
);
SWIFT_INLINE_BITFIELD_FULL(ObjectLiteralExpr, LiteralExpr, 3+1+1+16,
LitKind : 3,
/// Whether the ObjectLiteralExpr also has source locations for the argument
/// label.
HasArgLabelLocs : 1,
/// Whether the last argument is a trailing closure.
HasTrailingClosure : 1,
: NumPadBits,
/// # of argument labels stored after the ObjectLiteralExpr.
NumArgLabels : 16
);
SWIFT_INLINE_BITFIELD(AbstractClosureExpr, Expr, (16-NumExprBits)+16,
: 16 - NumExprBits, // Align and leave room for subclasses
Discriminator : 16
);
SWIFT_INLINE_BITFIELD(AutoClosureExpr, AbstractClosureExpr, 2,
/// If the autoclosure was built for a curry thunk, the thunk kind is
/// stored here.
Kind : 2
);
SWIFT_INLINE_BITFIELD(ClosureExpr, AbstractClosureExpr, 1,
/// True if closure parameters were synthesized from anonymous closure
/// variables.
HasAnonymousClosureVars : 1
);
SWIFT_INLINE_BITFIELD_FULL(BindOptionalExpr, Expr, 16,
: NumPadBits,
Depth : 16
);
SWIFT_INLINE_BITFIELD_EMPTY(ImplicitConversionExpr, Expr);
SWIFT_INLINE_BITFIELD_FULL(DestructureTupleExpr, ImplicitConversionExpr, 16,
/// The number of elements in the tuple type being destructured.
NumElements : 16
);
SWIFT_INLINE_BITFIELD(ForceValueExpr, Expr, 1,
ForcedIUO : 1
);
SWIFT_INLINE_BITFIELD(InOutToPointerExpr, ImplicitConversionExpr, 1,
IsNonAccessing : 1
);
SWIFT_INLINE_BITFIELD(ArrayToPointerExpr, ImplicitConversionExpr, 1,
IsNonAccessing : 1
);
SWIFT_INLINE_BITFIELD_FULL(ErasureExpr, ImplicitConversionExpr, 32,
: NumPadBits,
NumConformances : 32
);
SWIFT_INLINE_BITFIELD_FULL(UnresolvedSpecializeExpr, Expr, 32,
: NumPadBits,
NumUnresolvedParams : 32
);
SWIFT_INLINE_BITFIELD_FULL(CaptureListExpr, Expr, 32,
: NumPadBits,
NumCaptures : 32
);
SWIFT_INLINE_BITFIELD(ApplyExpr, Expr, 1+1+1,
ThrowsIsSet : 1,
Throws : 1,
ImplicitlyAsync : 1
);
SWIFT_INLINE_BITFIELD_FULL(CallExpr, ApplyExpr, 1+1+16,
/// Whether the CallExpr also has source locations for the argument label.
HasArgLabelLocs : 1,
/// Whether the last argument is a trailing closure.
HasTrailingClosure : 1,
: NumPadBits,
/// # of argument labels stored after the CallExpr.
NumArgLabels : 16
);
enum { NumCheckedCastKindBits = 4 };
SWIFT_INLINE_BITFIELD(CheckedCastExpr, Expr, NumCheckedCastKindBits,
CastKind : NumCheckedCastKindBits
);
static_assert(unsigned(CheckedCastKind::Last_CheckedCastKind)
< (1 << NumCheckedCastKindBits),
"unable to fit a CheckedCastKind in the given number of bits");
SWIFT_INLINE_BITFIELD_EMPTY(CollectionUpcastConversionExpr, Expr);
SWIFT_INLINE_BITFIELD(ObjCSelectorExpr, Expr, 2,
/// The selector kind.
SelectorKind : 2
);
SWIFT_INLINE_BITFIELD(KeyPathExpr, Expr, 1,
/// Whether this is an ObjC stringified keypath.
IsObjC : 1
);
SWIFT_INLINE_BITFIELD_FULL(SequenceExpr, Expr, 32,
: NumPadBits,
NumElements : 32
);
SWIFT_INLINE_BITFIELD(OpaqueValueExpr, Expr, 1,
IsPlaceholder : 1
);
} Bits;
private:
/// Ty - This is the type of the expression.
Type Ty;
protected:
Expr(ExprKind Kind, bool Implicit, Type Ty = Type()) : Ty(Ty) {
Bits.OpaqueBits = 0;
Bits.Expr.Kind = unsigned(Kind);
Bits.Expr.Implicit = Implicit;
}
public:
/// Return the kind of this expression.
ExprKind getKind() const { return ExprKind(Bits.Expr.Kind); }
/// Retrieve the name of the given expression kind.
///
/// This name should only be used for debugging dumps and other
/// developer aids, and should never be part of a diagnostic or exposed
/// to the user of the compiler in any way.
static StringRef getKindName(ExprKind K);
/// getType - Return the type of this expression.
Type getType() const { return Ty; }
/// setType - Sets the type of this expression.
void setType(Type T);
/// Return the source range of the expression.
SourceRange getSourceRange() const;
/// getStartLoc - Return the location of the start of the expression.
SourceLoc getStartLoc() const;
/// Retrieve the location of the last token of the expression.
SourceLoc getEndLoc() const;
/// getLoc - Return the caret location of this expression.
SourceLoc getLoc() const;
#define SWIFT_FORWARD_SOURCE_LOCS_TO(SUBEXPR) \
SourceLoc getStartLoc() const { return (SUBEXPR)->getStartLoc(); } \
SourceLoc getEndLoc() const { return (SUBEXPR)->getEndLoc(); } \
SourceLoc getLoc() const { return (SUBEXPR)->getLoc(); } \
SourceRange getSourceRange() const { return (SUBEXPR)->getSourceRange(); }
SourceLoc TrailingSemiLoc;
/// getSemanticsProvidingExpr - Find the smallest subexpression
/// which obeys the property that evaluating it is exactly
/// equivalent to evaluating this expression.
///
/// Looks through parentheses. Would not look through something
/// like '(foo(), x:bar(), baz()).x'.
Expr *getSemanticsProvidingExpr();
const Expr *getSemanticsProvidingExpr() const {
return const_cast<Expr *>(this)->getSemanticsProvidingExpr();
}
/// getValueProvidingExpr - Find the smallest subexpression which is
/// responsible for generating the value of this expression.
/// Evaluating the result is not necessarily equivalent to
/// evaluating this expression because of potential missing
/// side-effects (which may influence the returned value).
Expr *getValueProvidingExpr();
const Expr *getValueProvidingExpr() const {
return const_cast<Expr *>(this)->getValueProvidingExpr();
}
/// If this is a reference to an operator written as a member of a type (or
/// extension thereof), return the underlying operator reference.
DeclRefExpr *getMemberOperatorRef();
/// This recursively walks the AST rooted at this expression.
Expr *walk(ASTWalker &walker);
Expr *walk(ASTWalker &&walker) { return walk(walker); }
/// Enumerate each immediate child expression of this node, invoking the
/// specific functor on it. This ignores statements and other non-expression
/// children.
void forEachImmediateChildExpr(llvm::function_ref<Expr *(Expr *)> callback);
/// Enumerate each expr node within this expression subtree, invoking the
/// specific functor on it. This ignores statements and other non-expression
/// children, and if there is a closure within the expression, this does not
/// walk into the body of it (unless it is single-expression).
void forEachChildExpr(llvm::function_ref<Expr *(Expr *)> callback);
/// Determine whether this expression refers to a type by name.
///
/// This distinguishes static references to types, like Int, from metatype
/// values, "someTy: Any.Type".
bool isTypeReference(
llvm::function_ref<Type(Expr *)> getType = [](Expr *E) -> Type {
return E->getType();
},
llvm::function_ref<Decl *(Expr *)> getDecl = [](Expr *E) -> Decl * {
return nullptr;
}) const;
/// Determine whether this expression refers to a statically-derived metatype.
///
/// This implies `isTypeReference`, but also requires that the referenced type
/// is not an archetype or dependent type.
bool isStaticallyDerivedMetatype(
llvm::function_ref<Type(Expr *)> getType = [](Expr *E) -> Type {
return E->getType();
},
llvm::function_ref<bool(Expr *)> isTypeReference =
[](Expr *E) { return E->isTypeReference(); }) const;
/// isImplicit - Determines whether this expression was implicitly-generated,
/// rather than explicitly written in the AST.
bool isImplicit() const {
return Bits.Expr.Implicit;
}
void setImplicit(bool Implicit = true);
/// Retrieves the declaration that is being referenced by this
/// expression, if any.
ConcreteDeclRef getReferencedDecl(bool stopAtParenExpr = false) const;
/// Determine whether this expression is 'super', possibly converted to
/// a base class.
bool isSuperExpr() const;
/// Returns whether the semantically meaningful content of this expression is
/// an inout expression.
///
/// FIXME(Remove InOutType): This should eventually sub-in for
/// 'E->getType()->is<InOutType>()' in all cases.
bool isSemanticallyInOutExpr() const {
return getSemanticsProvidingExpr()->getKind() == ExprKind::InOut;
}
/// Returns false if this expression needs to be wrapped in parens when
/// used inside of a any postfix expression, true otherwise.
///
/// \param appendingPostfixOperator if the expression being
/// appended is a postfix operator like '!' or '?'.
bool canAppendPostfixExpression(bool appendingPostfixOperator = false) const;
/// Returns true if this is an infix operator of some sort, including
/// a builtin operator.
bool isInfixOperator() const;
/// Returns true if this is a reference to the implicit self of function.
bool isSelfExprOf(const AbstractFunctionDecl *AFD,
bool sameBase = false) const;
/// Given that this is a packed argument expression of the sort that
/// would be produced from packSingleArgument, return the index of the
/// unlabeled trailing closure, if there is one.
Optional<unsigned> getUnlabeledTrailingClosureIndexOfPackedArgument() const;
/// Produce a mapping from each subexpression to its parent
/// expression, with the provided expression serving as the root of
/// the parent map.
llvm::DenseMap<Expr *, Expr *> getParentMap();
SWIFT_DEBUG_DUMP;
void dump(raw_ostream &OS, unsigned Indent = 0) const;
void dump(raw_ostream &OS, llvm::function_ref<Type(Expr *)> getType,
llvm::function_ref<Type(TypeRepr *)> getTypeOfTypeRepr,
llvm::function_ref<Type(KeyPathExpr *E, unsigned index)>
getTypeOfKeyPathComponent,
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;
Expr *OriginalExpr;
public:
ErrorExpr(SourceRange Range, Type Ty = Type(), Expr *OriginalExpr = nullptr)
: Expr(ExprKind::Error, /*Implicit=*/true, Ty), Range(Range),
OriginalExpr(OriginalExpr) {}
SourceRange getSourceRange() const { return Range; }
Expr *getOriginalExpr() const { return OriginalExpr; }
static bool classof(const Expr *E) {
return E->getKind() == ExprKind::Error;
}
};
/// CodeCompletionExpr - Represents the code completion token in the AST, this
/// can help us preserve the context of the code completion position.
class CodeCompletionExpr : public Expr {
Expr *Base;
SourceLoc Loc;
public:
CodeCompletionExpr(Expr *Base, SourceLoc Loc)
: Expr(ExprKind::CodeCompletion, /*Implicit=*/true, Type()),
Base(Base), Loc(Loc) {}
CodeCompletionExpr(SourceLoc Loc)
: CodeCompletionExpr(/*Base=*/nullptr, Loc) {}
Expr *getBase() const { return Base; }
void setBase(Expr *E) { Base = E; }
SourceLoc getLoc() const { return Loc; }
SourceLoc getStartLoc() const { return Base ? Base->getStartLoc() : Loc; }
SourceLoc getEndLoc() const { return Loc; }
static bool classof(const Expr *E) {
return E->getKind() == ExprKind::CodeCompletion;
}
};
/// LiteralExpr - Common base class between the literals.
class LiteralExpr : public Expr {
// Set by Sema:
ConcreteDeclRef Initializer;
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;
}
/// Retrieve the initializer that will be used to construct the
/// literal from the result of the initializer.
///
/// Only literals that have no builtin literal conformance will have
/// this initializer, which will be called on the result of the builtin
/// initializer.
ConcreteDeclRef getInitializer() const { return Initializer; }
/// Set the initializer that will be used to construct the literal.
void setInitializer(ConcreteDeclRef initializer) {
Initializer = initializer;
}
};
/// BuiltinLiteralExpr - Common base class between all literals
/// that provides BuiltinInitializer
class BuiltinLiteralExpr : public LiteralExpr {
// Set by Seam:
ConcreteDeclRef BuiltinInitializer;
public:
BuiltinLiteralExpr(ExprKind Kind, bool Implicit)
: LiteralExpr(Kind, Implicit) {}
static bool classof(const Expr *E) {
return E->getKind() >= ExprKind::First_BuiltinLiteralExpr &&
E->getKind() <= ExprKind::Last_BuiltinLiteralExpr;
}
/// Retrieve the builtin initializer that will be used to construct the
/// literal.
///
/// Any type-checked literal will have a builtin initializer, which is
/// called first to form a concrete Swift type.
ConcreteDeclRef getBuiltinInitializer() const { return BuiltinInitializer; }
/// Set the builtin initializer that will be used to construct the
/// literal.
void setBuiltinInitializer(ConcreteDeclRef builtinInitializer) {
BuiltinInitializer = builtinInitializer;
}
};
/// The 'nil' literal.
///
class NilLiteralExpr : public LiteralExpr {
SourceLoc Loc;
public:
NilLiteralExpr(SourceLoc Loc, bool Implicit = false)
: LiteralExpr(ExprKind::NilLiteral, Implicit), Loc(Loc) {
}
SourceRange getSourceRange() const {
return Loc;
}
static bool classof(const Expr *E) {
return E->getKind() == ExprKind::NilLiteral;
}
};
/// Abstract base class for numeric literals, potentially with a sign.
class NumberLiteralExpr : public BuiltinLiteralExpr {
/// The value of the literal as an ASTContext-owned string. Underscores must
/// be stripped.
StringRef Val; // Use StringRef instead of APInt or APFloat, which leak.
protected:
SourceLoc MinusLoc;
SourceLoc DigitsLoc;
public:
NumberLiteralExpr(ExprKind Kind, StringRef Val, SourceLoc DigitsLoc,
bool Implicit)
: BuiltinLiteralExpr(Kind, Implicit), Val(Val), DigitsLoc(DigitsLoc) {
Bits.NumberLiteralExpr.IsNegative = false;
Bits.NumberLiteralExpr.IsExplicitConversion = false;
}
bool isNegative() const { return Bits.NumberLiteralExpr.IsNegative; }
void setNegative(SourceLoc Loc) {
MinusLoc = Loc;
Bits.NumberLiteralExpr.IsNegative = true;
}
bool isExplicitConversion() const {
return Bits.NumberLiteralExpr.IsExplicitConversion;
}
void setExplicitConversion(bool isExplicitConversion = true) {
Bits.NumberLiteralExpr.IsExplicitConversion = isExplicitConversion;
}
StringRef getDigitsText() const { return Val; }
SourceRange getSourceRange() const {
if (isNegative())
return { MinusLoc, DigitsLoc };
else
return DigitsLoc;
}
SourceLoc getMinusLoc() const {
return MinusLoc;
}
SourceLoc getDigitsLoc() const {
return DigitsLoc;
}
static bool classof(const Expr *E) {
return E->getKind() >= ExprKind::First_NumberLiteralExpr
&& E->getKind() <= ExprKind::Last_NumberLiteralExpr;
}
};
/// Integer literal with a '+' or '-' sign, like '+4' or '- 2'.
///
/// After semantic analysis assigns types, this is guaranteed to have
/// a BuiltinIntegerType or be a normal type and implicitly be
/// AnyBuiltinIntegerType.
class IntegerLiteralExpr : public NumberLiteralExpr {
public:
IntegerLiteralExpr(StringRef Val, SourceLoc DigitsLoc, bool Implicit = false)
: NumberLiteralExpr(ExprKind::IntegerLiteral,
Val, DigitsLoc, Implicit)
{}
/// Returns a new integer literal expression with the given value.
/// \p C The AST context.
/// \p value The integer value.
/// \return An implicit integer literal expression which evaluates to the value.
static IntegerLiteralExpr *
createFromUnsigned(ASTContext &C, unsigned value);
/// Returns the value of the literal, appropriately constructed in the
/// target type.
APInt getValue() const;
/// Returns the raw value of the literal without any truncation.
APInt getRawValue() const;
static bool classof(const Expr *E) {
return E->getKind() == ExprKind::IntegerLiteral;
}
};
/// FloatLiteralExpr - Floating point literal, like '4.0'. After semantic
/// analysis assigns types, BuiltinTy is guaranteed to only have a
/// BuiltinFloatingPointType.
class FloatLiteralExpr : public NumberLiteralExpr {
/// This is the type of the builtin literal.
Type BuiltinTy;
public:
FloatLiteralExpr(StringRef Val, SourceLoc Loc, bool Implicit = false)
: NumberLiteralExpr(ExprKind::FloatLiteral, Val, Loc, Implicit)
{}
APFloat getValue() const;
static APFloat getValue(StringRef Text, const llvm::fltSemantics &Semantics,
bool Negative);
static bool classof(const Expr *E) {
return E->getKind() == ExprKind::FloatLiteral;
}
Type getBuiltinType() const { return BuiltinTy; }
void setBuiltinType(Type ty) { BuiltinTy = ty; }
};
/// A Boolean literal ('true' or 'false')
///
class BooleanLiteralExpr : public BuiltinLiteralExpr {
SourceLoc Loc;
public:
BooleanLiteralExpr(bool Value, SourceLoc Loc, bool Implicit = false)
: BuiltinLiteralExpr(ExprKind::BooleanLiteral, Implicit), Loc(Loc) {
Bits.BooleanLiteralExpr.Value = Value;
}
/// Retrieve the Boolean value of this literal.
bool getValue() const { return Bits.BooleanLiteralExpr.Value; }
SourceRange getSourceRange() const {
return Loc;
}
static bool classof(const Expr *E) {
return E->getKind() == ExprKind::BooleanLiteral;
}
};
/// StringLiteralExpr - String literal, like '"foo"'.
class StringLiteralExpr : public BuiltinLiteralExpr {
StringRef Val;
SourceRange Range;
public:
/// The encoding that should be used for the string literal.
enum Encoding : unsigned {
/// A UTF-8 string.
UTF8,
/// A single UnicodeScalar, passed as an integer.
OneUnicodeScalar
};
StringLiteralExpr(StringRef Val, SourceRange Range, bool Implicit = false);
StringRef getValue() const { return Val; }
SourceRange getSourceRange() const { return Range; }
/// Determine the encoding that should be used for this string literal.
Encoding getEncoding() const {
return static_cast<Encoding>(Bits.StringLiteralExpr.Encoding);
}
/// Set the encoding that should be used for this string literal.
void setEncoding(Encoding encoding) {
Bits.StringLiteralExpr.Encoding = static_cast<unsigned>(encoding);
}
bool isSingleUnicodeScalar() const {
return Bits.StringLiteralExpr.IsSingleUnicodeScalar;
}
bool isSingleExtendedGraphemeCluster() const {
return Bits.StringLiteralExpr.IsSingleExtendedGraphemeCluster;
}
static bool classof(const Expr *E) {
return E->getKind() == ExprKind::StringLiteral;
}
};
/// Runs a series of statements which use or modify \c SubExpr
/// before it is given to the rest of the expression.
///
/// \c Body should begin with a \c VarDecl; this defines the variable
/// \c TapExpr will initialize at the beginning and read a result
/// from at the end. \c TapExpr creates a separate scope, then
/// assigns the result of \c SubExpr to the variable and runs \c Body
/// in it, returning the value of the variable after the \c Body runs.
///
/// (The design here could be a bit cleaner, particularly where the VarDecl
/// is concerned.)
class TapExpr : public Expr {
Expr *SubExpr;
BraceStmt *Body;
public:
TapExpr(Expr *SubExpr, BraceStmt *Body);
Expr * getSubExpr() const { return SubExpr; }
void setSubExpr(Expr * se) { SubExpr = se; }
/// The variable which will be accessed and possibly modified by
/// the \c Body. This is the first \c ASTNode in the \c Body.
VarDecl * getVar() const;
BraceStmt * getBody() const { return Body; }
void setBody(BraceStmt * b) { Body = b; }
SourceLoc getLoc() const { return SubExpr ? SubExpr->getLoc() : SourceLoc(); }
SourceLoc getStartLoc() const {
return SubExpr ? SubExpr->getStartLoc() : SourceLoc();
}
SourceLoc getEndLoc() const;
static bool classof(const Expr *E) {
return E->getKind() == ExprKind::Tap;
}
};
/// InterpolatedStringLiteral - An interpolated string literal.
///
/// An interpolated string literal mixes expressions (which are evaluated and
/// converted into string form) within a string literal.
///
/// \code
/// "[\(min)..\(max)]"
/// \endcode
class InterpolatedStringLiteralExpr : public LiteralExpr {
/// Points at the beginning quote.
SourceLoc Loc;
/// Points at the ending quote.
/// Needed for the upcoming \c ASTScope subsystem because lookups can be
/// targeted to inside an \c InterpolatedStringLiteralExpr. It would be nicer
/// to use \c EndLoc for this value, but then \c Lexer::getLocForEndOfToken()
/// would not work for \c stringLiteral->getEndLoc().
SourceLoc TrailingQuoteLoc;
TapExpr *AppendingExpr;
// Set by Sema:
OpaqueValueExpr *interpolationExpr = nullptr;
ConcreteDeclRef builderInit;
Expr *interpolationCountExpr = nullptr;
Expr *literalCapacityExpr = nullptr;
public:
InterpolatedStringLiteralExpr(SourceLoc Loc,
SourceLoc TrailingQuoteLoc,
unsigned LiteralCapacity,
unsigned InterpolationCount,
TapExpr *AppendingExpr)
: LiteralExpr(ExprKind::InterpolatedStringLiteral, /*Implicit=*/false),
Loc(Loc),
TrailingQuoteLoc(TrailingQuoteLoc),
AppendingExpr(AppendingExpr) {
Bits.InterpolatedStringLiteralExpr.InterpolationCount = InterpolationCount;
Bits.InterpolatedStringLiteralExpr.LiteralCapacity = LiteralCapacity;
}
// Sets the constructor for the interpolation type.
void setBuilderInit(ConcreteDeclRef decl) { builderInit = decl; }
ConcreteDeclRef getBuilderInit() const { return builderInit; }
/// Sets the OpaqueValueExpr that is passed into AppendingExpr as the SubExpr
/// that the tap operates on.
void setInterpolationExpr(OpaqueValueExpr *expr) { interpolationExpr = expr; }
OpaqueValueExpr *getInterpolationExpr() const { return interpolationExpr; }
/// Store a builtin integer literal expr wrapping getInterpolationCount().
/// This is an arg to builderInit.
void setInterpolationCountExpr(Expr *expr) { interpolationCountExpr = expr; }
Expr *getInterpolationCountExpr() const { return interpolationCountExpr; }
/// Store a builtin integer literal expr wrapping getLiteralCapacity().
/// This is an arg to builderInit.
void setLiteralCapacityExpr(Expr *expr) { literalCapacityExpr = expr; }
Expr *getLiteralCapacityExpr() const { return literalCapacityExpr; }
/// Retrieve the value of the literalCapacity parameter to the
/// initializer.
unsigned getLiteralCapacity() const {
return Bits.InterpolatedStringLiteralExpr.LiteralCapacity;
}
/// Retrieve the value of the interpolationCount parameter to the
/// initializer.
unsigned getInterpolationCount() const {
return Bits.InterpolatedStringLiteralExpr.InterpolationCount;
}
/// A block containing expressions which call
/// \c StringInterpolationProtocol methods to append segments to the
/// string interpolation. The first node in \c Body should be an uninitialized
/// \c VarDecl; the other statements should append to it.
TapExpr * getAppendingExpr() const { return AppendingExpr; }
void setAppendingExpr(TapExpr * AE) { AppendingExpr = AE; }
SourceLoc getStartLoc() const {
return Loc;
}
SourceLoc getEndLoc() const {
// SourceLocs are token based, and the interpolated string is one string
// token, so the range should be (Start == End).
return Loc;
}
/// Could also be computed by relexing.
SourceLoc getTrailingQuoteLoc() const {
return TrailingQuoteLoc;
}
/// Call the \c callback with information about each segment in turn.
void forEachSegment(ASTContext &Ctx,
llvm::function_ref<void(bool, CallExpr *)> callback);
static bool classof(const Expr *E) {
return E->getKind() == ExprKind::InterpolatedStringLiteral;
}
};
/// MagicIdentifierLiteralExpr - A magic identifier like #file which expands
/// out to a literal at SILGen time.
class MagicIdentifierLiteralExpr : public BuiltinLiteralExpr {
public:
enum Kind : unsigned {
#define MAGIC_IDENTIFIER(NAME, STRING, SYNTAX_KIND) NAME,
#include "swift/AST/MagicIdentifierKinds.def"
};
static StringRef getKindString(MagicIdentifierLiteralExpr::Kind value) {
switch (value) {
#define MAGIC_IDENTIFIER(NAME, STRING, SYNTAX_KIND) case NAME: return STRING;
#include "swift/AST/MagicIdentifierKinds.def"
}
llvm_unreachable("Unhandled MagicIdentifierLiteralExpr in getKindString.");
}
private:
SourceLoc Loc;
public:
MagicIdentifierLiteralExpr(Kind kind, SourceLoc loc, bool implicit = false)
: BuiltinLiteralExpr(ExprKind::MagicIdentifierLiteral, implicit),
Loc(loc) {
Bits.MagicIdentifierLiteralExpr.Kind = static_cast<unsigned>(kind);
Bits.MagicIdentifierLiteralExpr.StringEncoding
= static_cast<unsigned>(StringLiteralExpr::UTF8);
}
Kind getKind() const {
return static_cast<Kind>(Bits.MagicIdentifierLiteralExpr.Kind);
}
bool isString() const {
switch (getKind()) {
#define MAGIC_STRING_IDENTIFIER(NAME, STRING, SYNTAX_KIND) \
case NAME: \
return true;
#define MAGIC_IDENTIFIER(NAME, STRING, SYNTAX_KIND) \
case NAME: \
return false;
#include "swift/AST/MagicIdentifierKinds.def"
}
llvm_unreachable("bad Kind");
}
SourceRange getSourceRange() const { return Loc; }
// For a magic identifier that produces a string literal, retrieve the
// encoding for that string literal.
StringLiteralExpr::Encoding getStringEncoding() const {
assert(isString() && "Magic identifier literal has non-string encoding");
return static_cast<StringLiteralExpr::Encoding>(
Bits.MagicIdentifierLiteralExpr.StringEncoding);
}
// For a magic identifier that produces a string literal, set the encoding
// for the string literal.
void setStringEncoding(StringLiteralExpr::Encoding encoding) {
assert(isString() && "Magic identifier literal has non-string encoding");
Bits.MagicIdentifierLiteralExpr.StringEncoding
= static_cast<unsigned>(encoding);
}
static bool classof(const Expr *E) {
return E->getKind() == ExprKind::MagicIdentifierLiteral;
}
};
// ObjectLiteralExpr - An expression of the form
// '#colorLiteral(red: 1, blue: 0, green: 0, alpha: 1)' with a name and a list
// argument. The components of the list argument are meant to be themselves
// constant.
class ObjectLiteralExpr final
: public LiteralExpr,
public TrailingCallArguments<ObjectLiteralExpr> {
public:
/// The kind of object literal.
enum LiteralKind : unsigned {
#define POUND_OBJECT_LITERAL(Name, Desc, Proto) Name,
#include "swift/Syntax/TokenKinds.def"
};
private:
Expr *Arg;
SourceLoc PoundLoc;
ObjectLiteralExpr(SourceLoc PoundLoc, LiteralKind LitKind,
Expr *Arg,
ArrayRef<Identifier> argLabels,
ArrayRef<SourceLoc> argLabelLocs,
bool hasTrailingClosure,
bool implicit);
public:
/// Create a new object literal expression.
///
/// Note: prefer to use the second entry point, which separates out
/// arguments/labels/etc.
static ObjectLiteralExpr *create(ASTContext &ctx, SourceLoc poundLoc,
LiteralKind kind, Expr *arg, bool implicit,
llvm::function_ref<Type(Expr *)> getType);
/// Create a new object literal expression.
static ObjectLiteralExpr *create(ASTContext &ctx, SourceLoc poundLoc,
LiteralKind kind,
SourceLoc lParenLoc,
ArrayRef<Expr *> args,
ArrayRef<Identifier> argLabels,
ArrayRef<SourceLoc> argLabelLocs,
SourceLoc rParenLoc,
ArrayRef<TrailingClosure> trailingClosures,
bool implicit);
LiteralKind getLiteralKind() const {
return static_cast<LiteralKind>(Bits.ObjectLiteralExpr.LitKind);
}
Expr *getArg() const { return Arg; }
void setArg(Expr *arg) { Arg = arg; }
unsigned getNumArguments() const {
return Bits.ObjectLiteralExpr.NumArgLabels;
}
bool hasArgumentLabelLocs() const {
return Bits.ObjectLiteralExpr.HasArgLabelLocs;
}
/// Whether this call with written with a trailing closure.
bool hasTrailingClosure() const {
return Bits.ObjectLiteralExpr.HasTrailingClosure;
}
/// Return the index of the unlabeled trailing closure argument.
Optional<unsigned> getUnlabeledTrailingClosureIndex() const {
return getArg()->getUnlabeledTrailingClosureIndexOfPackedArgument();
}
SourceLoc getSourceLoc() const { return PoundLoc; }
SourceRange getSourceRange() const {
return SourceRange(PoundLoc, Arg->getEndLoc());
}
/// Return the string form of the literal name.
StringRef getLiteralKindRawName() const;
StringRef getLiteralKindPlainName() const;
static bool classof(const Expr *E) {
return E->getKind() == ExprKind::ObjectLiteral;
}
};
/// DiscardAssignmentExpr - A '_' in the left-hand side of an assignment, which
/// discards the corresponding tuple element on the right-hand side.
class DiscardAssignmentExpr : public Expr {
SourceLoc Loc;
public:
DiscardAssignmentExpr(SourceLoc Loc, bool Implicit)
: Expr(ExprKind::DiscardAssignment, Implicit), Loc(Loc) {}
SourceRange getSourceRange() const { return Loc; }
SourceLoc getLoc() const { return Loc; }
static bool classof(const Expr *E) {
return E->getKind() == ExprKind::DiscardAssignment;
}
};
/// DeclRefExpr - A reference to a value, "x".
class DeclRefExpr : public Expr {
/// The declaration pointer.
ConcreteDeclRef D;
DeclNameLoc Loc;
public:
DeclRefExpr(ConcreteDeclRef D, DeclNameLoc Loc, bool Implicit,
AccessSemantics semantics = AccessSemantics::Ordinary,
Type Ty = Type())
: Expr(ExprKind::DeclRef, Implicit, Ty), D(D), Loc(Loc) {
Bits.DeclRefExpr.Semantics = (unsigned) semantics;
Bits.DeclRefExpr.FunctionRefKind =
static_cast<unsigned>(Loc.isCompound() ? FunctionRefKind::Compound
: FunctionRefKind::Unapplied);
}
/// Retrieve the declaration to which this expression refers.
ValueDecl *getDecl() const {
return getDeclRef().getDecl();
}
/// Return true if this access is direct, meaning that it does not call the
/// getter or setter.
AccessSemantics getAccessSemantics() const {
return (AccessSemantics) Bits.DeclRefExpr.Semantics;
}
/// Retrieve the concrete declaration reference.
ConcreteDeclRef getDeclRef() const {
return D;
}
SourceRange getSourceRange() const { return Loc.getSourceRange(); }
SourceLoc getLoc() const { return Loc.getBaseNameLoc(); }
DeclNameLoc getNameLoc() const { return Loc; }
/// Retrieve the kind of function reference.
FunctionRefKind getFunctionRefKind() const {
return static_cast<FunctionRefKind>(Bits.DeclRefExpr.FunctionRefKind);
}
/// Set the kind of function reference.
void setFunctionRefKind(FunctionRefKind refKind) {
Bits.DeclRefExpr.FunctionRefKind = static_cast<unsigned>(refKind);
}
static bool classof(const Expr *E) {
return E->getKind() == ExprKind::DeclRef;
}
};
/// A reference to 'super'. References to members of 'super' resolve to members
/// of a superclass of 'self'.
class SuperRefExpr : public Expr {
VarDecl *Self;
SourceLoc Loc;
public:
SuperRefExpr(VarDecl *Self, SourceLoc Loc, bool Implicit,
Type SuperTy = Type())
: Expr(ExprKind::SuperRef, Implicit, SuperTy), Self(Self), Loc(Loc) {}
VarDecl *getSelf() const { return Self; }
void setSelf(VarDecl *self) { Self = 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.
///
/// The type of this expression is always \c MetatypeType.
class TypeExpr : public Expr {
TypeRepr *Repr;
public:
/// Create a \c TypeExpr from a parsed \c TypeRepr.
TypeExpr(TypeRepr *Ty);
/// Retrieves the corresponding instance type of the type referenced by this
/// expression.
///
/// If this node has no type, the resulting instance type is also the
/// null \c Type(). If the type of this node is not a \c MetatypeType, the
/// resulting instance type is \c ErrorType.
Type getInstanceType() const;
public:
/// Create an implicit \c TypeExpr.
///
/// The given type is required to be non-null and must be not be
/// a \c MetatypeType as this function will wrap the given type in one.
///
/// FIXME: This behavior is bizarre.
static TypeExpr *createImplicit(Type Ty, ASTContext &C);
/// Create an implicit \c TypeExpr that has artificial
/// location information attached.
///
/// The given type is required to be non-null and must be not be
/// a \c MetatypeType as this function will wrap the given type in one.
///
/// FIXME: This behavior is bizarre.
///
/// Due to limitations in the modeling of certain AST elements, implicit
/// \c TypeExpr nodes are often the only source of location information the
/// expression checker has when it comes time to diagnose an error.
static TypeExpr *createImplicitHack(SourceLoc Loc, Type Ty, ASTContext &C);
/// Create an implicit \c TypeExpr for a given \c TypeDecl at the specified location.
///
/// The given type is required to be non-null and must be not be
/// a \c MetatypeType as this function will wrap the given type in one.
///
/// FIXME: This behavior is bizarre.
///
/// Unlike the non-implicit case, the given location is not required to be
/// valid.
static TypeExpr *createImplicitForDecl(DeclNameLoc Loc, TypeDecl *D,
DeclContext *DC, Type ty);
public:
/// Create a \c TypeExpr for a given \c TypeDecl at the specified location.
///
/// The given location must be valid. If it is not, you must use
/// \c TypeExpr::createImplicitForDecl instead.
static TypeExpr *createForDecl(DeclNameLoc Loc, TypeDecl *D, DeclContext *DC);
/// Create a TypeExpr for a member TypeDecl of the given parent TypeDecl.
static TypeExpr *createForMemberDecl(DeclNameLoc ParentNameLoc,
TypeDecl *Parent,
DeclNameLoc NameLoc,
TypeDecl *Decl);
/// Create a TypeExpr for a member TypeDecl of the given parent IdentTypeRepr.
static TypeExpr *createForMemberDecl(IdentTypeRepr *ParentTR,
DeclNameLoc NameLoc,
TypeDecl *Decl);
/// Create a TypeExpr from an IdentTypeRepr with the given arguments applied
/// at the specified location.
///
/// Returns nullptr if the reference cannot be formed, which is a hack due
/// to limitations in how we model generic typealiases.
static TypeExpr *createForSpecializedDecl(IdentTypeRepr *ParentTR,
ArrayRef<TypeRepr*> Args,
SourceRange AngleLocs,
ASTContext &C);
TypeRepr *getTypeRepr() const { return Repr; }
// 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;
// TODO: optimize getStartLoc() and getEndLoc() when TypeLoc allows it.
static bool classof(const Expr *E) {
return E->getKind() == ExprKind::Type;
}
};
/// A reference to another initializer from within a constructor body,
/// either to a delegating initializer or to a super.init invocation.
/// For a reference type, this semantically references a different constructor
/// entry point, called the 'initializing constructor', from the 'allocating
/// constructor' entry point referenced by a 'new' expression.
class OtherConstructorDeclRefExpr : public Expr {
ConcreteDeclRef Ctor;
DeclNameLoc Loc;
public:
OtherConstructorDeclRefExpr(ConcreteDeclRef Ctor, DeclNameLoc Loc,
bool Implicit, Type Ty = {})
: Expr(ExprKind::OtherConstructorDeclRef, Implicit, Ty),
Ctor(Ctor), Loc(Loc)
{}
ConstructorDecl *getDecl() const;
ConcreteDeclRef getDeclRef() const { return Ctor; }
SourceLoc getLoc() const { return Loc.getBaseNameLoc(); }
DeclNameLoc getConstructorLoc() const { return Loc; }
SourceRange getSourceRange() const { return Loc.getSourceRange(); }
static bool classof(const Expr *E) {
return E->getKind() == ExprKind::OtherConstructorDeclRef;
}
};
/// OverloadSetRefExpr - A reference to an overloaded set of values with a
/// single name.
///
/// This is an abstract class that covers the various different kinds of
/// overload sets.
class OverloadSetRefExpr : public Expr {
ArrayRef<ValueDecl*> Decls;
protected:
OverloadSetRefExpr(ExprKind Kind, ArrayRef<ValueDecl*> decls,
FunctionRefKind functionRefKind, bool Implicit, Type Ty)
: Expr(Kind, Implicit, Ty), Decls(decls) {
Bits.OverloadSetRefExpr.FunctionRefKind =
static_cast<unsigned>(functionRefKind);
}
public:
ArrayRef<ValueDecl*> getDecls() const { return Decls; }
void setDecls(ArrayRef<ValueDecl *> domain) {
Decls = domain;
}
/// getBaseType - Determine the type of the base object provided for the
/// given overload set, which is only non-null when dealing with an overloaded
/// member reference.
Type getBaseType() const;
/// hasBaseObject - Determine whether this overloaded expression has a
/// concrete base object (which is not a metatype).
bool hasBaseObject() const;
/// Retrieve the kind of function reference.
FunctionRefKind getFunctionRefKind() const {
return static_cast<FunctionRefKind>(
Bits.OverloadSetRefExpr.FunctionRefKind);
}
/// Set the kind of function reference.
void setFunctionRefKind(FunctionRefKind refKind) {
Bits.OverloadSetRefExpr.FunctionRefKind = static_cast<unsigned>(refKind);
}
static bool classof(const Expr *E) {
return E->getKind() >= ExprKind::First_OverloadSetRefExpr &&
E->getKind() <= ExprKind::Last_OverloadSetRefExpr;
}
};
/// OverloadedDeclRefExpr - A reference to an overloaded name that should
/// eventually be resolved (by overload resolution) to a value reference.
class OverloadedDeclRefExpr final : public OverloadSetRefExpr {
DeclNameLoc Loc;
public:
OverloadedDeclRefExpr(ArrayRef<ValueDecl*> Decls, DeclNameLoc Loc,
FunctionRefKind functionRefKind,
bool Implicit, Type Ty = Type())
: OverloadSetRefExpr(ExprKind::OverloadedDeclRef, Decls, functionRefKind,
Implicit, Ty),
Loc(Loc) {
}
DeclNameLoc getNameLoc() const { return Loc; }
SourceLoc getLoc() const { return Loc.getBaseNameLoc(); }
SourceRange getSourceRange() const { return Loc.getSourceRange(); }
static bool classof(const Expr *E) {
return E->getKind() == ExprKind::OverloadedDeclRef;
}
};
/// UnresolvedDeclRefExpr - This represents use of an undeclared identifier,
/// which may ultimately be a use of something that hasn't been defined yet, it
/// may be a use of something that got imported (which will be resolved during
/// sema), or may just be a use of an unknown identifier.
///
class UnresolvedDeclRefExpr : public Expr {
DeclNameRef Name;
DeclNameLoc Loc;
public:
UnresolvedDeclRefExpr(DeclNameRef name, DeclRefKind refKind, DeclNameLoc loc)
: Expr(ExprKind::UnresolvedDeclRef, /*Implicit=*/loc.isInvalid()),
Name(name), Loc(loc) {
Bits.UnresolvedDeclRefExpr.DeclRefKind = static_cast<unsigned>(refKind);
Bits.UnresolvedDeclRefExpr.FunctionRefKind =
static_cast<unsigned>(Loc.isCompound() ? FunctionRefKind::Compound
: FunctionRefKind::Unapplied);
}
static UnresolvedDeclRefExpr *createImplicit(
ASTContext &C, DeclName name,
DeclRefKind refKind = DeclRefKind::Ordinary) {
return new (C) UnresolvedDeclRefExpr(DeclNameRef(name), refKind,
DeclNameLoc());
}
static UnresolvedDeclRefExpr *createImplicit(
ASTContext &C, DeclBaseName baseName, ArrayRef<Identifier> argLabels) {
return UnresolvedDeclRefExpr::createImplicit(C,
DeclName(C, baseName, argLabels));
}
static UnresolvedDeclRefExpr *createImplicit(
ASTContext &C, DeclBaseName baseName, ParameterList *paramList) {
return UnresolvedDeclRefExpr::createImplicit(C,
DeclName(C, baseName, paramList));
}
bool hasName() const { return static_cast<bool>(Name); }
DeclNameRef getName() const { return Name; }
DeclRefKind getRefKind() const {
return static_cast<DeclRefKind>(Bits.UnresolvedDeclRefExpr.DeclRefKind);
}
/// Retrieve the kind of function reference.
FunctionRefKind getFunctionRefKind() const {
return static_cast<FunctionRefKind>(
Bits.UnresolvedDeclRefExpr.FunctionRefKind);
}
/// Set the kind of function reference.
void setFunctionRefKind(FunctionRefKind refKind) {
Bits.UnresolvedDeclRefExpr.FunctionRefKind = static_cast<unsigned>(refKind);
}
DeclNameLoc getNameLoc() const { return Loc; }
SourceRange getSourceRange() const { return Loc.getSourceRange(); }
static bool classof(const Expr *E) {
return E->getKind() == ExprKind::UnresolvedDeclRef;
}
};
/// LookupExpr - This abstract class represents 'a.b', 'a[]', etc where we
/// are referring to a member of a type, such as a property, variable, etc.
class LookupExpr : public Expr {
Expr *Base;
ConcreteDeclRef Member;
protected:
explicit LookupExpr(ExprKind Kind, Expr *base, ConcreteDeclRef member,
bool Implicit)
: Expr(Kind, Implicit), Base(base), Member(member) {
Bits.LookupExpr.IsSuper = false;
assert(Base);
}
public:
/// Retrieve the base of the expression.
Expr *getBase() const { return Base; }
/// Replace the base of the expression.
void setBase(Expr *E) { Base = E; }
/// Retrieve the member to which this access refers.
ConcreteDeclRef getMember() const { return Member; }
/// Determine whether the operation has a known underlying declaration or not.
bool hasDecl() const { return static_cast<bool>(Member); }
/// Retrieve the declaration that this /// operation refers to.
/// Only valid when \c hasDecl() is true.
ConcreteDeclRef getDecl() const {
assert(hasDecl() && "No subscript declaration known!");
return getMember();
}
/// Determine whether this reference refers to the superclass's property.
bool isSuper() const { return Bits.LookupExpr.IsSuper; }
/// Set whether this reference refers to the superclass's property.
void setIsSuper(bool isSuper) { Bits.LookupExpr.IsSuper = isSuper; }
static bool classof(const Expr *E) {
return E->getKind() >= ExprKind::First_LookupExpr &&
E->getKind() <= ExprKind::Last_LookupExpr;
}
};
/// MemberRefExpr - This represents 'a.b' where we are referring to a member
/// of a type, such as a property or variable.
///
/// Note that methods found via 'dot' syntax are expressed as DotSyntaxCallExpr
/// nodes, because 'a.f' is actually an application of 'a' (the implicit object
/// argument) to the function 'f'.
class MemberRefExpr : public LookupExpr {
SourceLoc DotLoc;
DeclNameLoc NameLoc;
public:
MemberRefExpr(Expr *base, SourceLoc dotLoc, ConcreteDeclRef member,
DeclNameLoc loc, bool Implicit,
AccessSemantics semantics = AccessSemantics::Ordinary);
SourceLoc getDotLoc() const { return DotLoc; }
DeclNameLoc getNameLoc() const { return NameLoc; }
/// Return true if this member access is direct, meaning that it
/// does not call the getter or setter.
AccessSemantics getAccessSemantics() const {
return (AccessSemantics) Bits.MemberRefExpr.Semantics;
}
SourceLoc getLoc() const { return NameLoc.getBaseNameLoc(); }
SourceLoc getStartLoc() const {
SourceLoc BaseStartLoc = getBase()->getStartLoc();
if (BaseStartLoc.isInvalid() || NameLoc.isInvalid()) {
return NameLoc.getBaseNameLoc();
} else {
return BaseStartLoc;
}
}
SourceLoc getEndLoc() const {
return NameLoc.getSourceRange().End;
}
static bool classof(const Expr *E) {
return E->getKind() == ExprKind::MemberRef;
}
};
/// Common base for expressions that involve dynamic lookup, which
/// determines at runtime whether a particular method, property, or
/// subscript is available.
class DynamicLookupExpr : public LookupExpr {
protected:
explicit DynamicLookupExpr(ExprKind kind, ConcreteDeclRef member, Expr *base)
: LookupExpr(kind, base, member, /*Implicit=*/false) { }
public:
static bool classof(const Expr *E) {
return E->getKind() >= ExprKind::First_DynamicLookupExpr &&
E->getKind() <= ExprKind::Last_DynamicLookupExpr;
}
};
/// A reference to a member of an object that was found via dynamic lookup.
///
/// A member found via dynamic lookup may not actually be available at runtime.
/// Therefore, a reference to that member always returns an optional instance.
/// Users can then propagate the optional (via ?) or assert that the member is
/// always available (via !). For example:
///
/// \code
/// class C {
/// func @objc foo(i : Int) -> String { ... }
/// };
///
/// var x : AnyObject = <some value>
/// print(x.foo!(17)) // x.foo has type ((i : Int) -> String)?
/// \endcode
class DynamicMemberRefExpr : public DynamicLookupExpr {
SourceLoc DotLoc;
DeclNameLoc NameLoc;
public:
DynamicMemberRefExpr(Expr *base, SourceLoc dotLoc,
ConcreteDeclRef member,
DeclNameLoc nameLoc)
: DynamicLookupExpr(ExprKind::DynamicMemberRef, member, base),
DotLoc(dotLoc), NameLoc(nameLoc) {
}
/// Retrieve the location of the member name.
DeclNameLoc getNameLoc() const { return NameLoc; }
/// Retrieve the location of the '.'.
SourceLoc getDotLoc() const { return DotLoc; }
SourceLoc getLoc() const { return NameLoc.getBaseNameLoc(); }
SourceLoc getStartLoc() const {
SourceLoc BaseStartLoc = getBase()->getStartLoc();
if (BaseStartLoc.isInvalid() || NameLoc.isInvalid()) {
return NameLoc.getBaseNameLoc();
} else {
return BaseStartLoc;
}
}
SourceLoc getEndLoc() const { return NameLoc.getSourceRange().End; }
static bool classof(const Expr *E) {
return E->getKind() == ExprKind::DynamicMemberRef;
}
};
/// A subscript on an object with dynamic lookup type.
///
/// A subscript found via dynamic lookup may not actually be available
/// at runtime. Therefore, the result of performing the subscript
/// operation always returns an optional instance.Users can then
/// propagate the optional (via ?) or assert that the member is always
/// available (via !). For example:
///
/// \code
/// class C {
/// @objc subscript (i : Int) -> String {
/// get {
/// ...
/// }
/// }
/// };
///
/// var x : AnyObject = <some value>
/// print(x[27]! // x[27] has type String?
/// \endcode
class DynamicSubscriptExpr final
: public DynamicLookupExpr,
public TrailingCallArguments<DynamicSubscriptExpr> {
friend TrailingCallArguments;
Expr *Index;
DynamicSubscriptExpr(Expr *base, Expr *index, ArrayRef<Identifier> argLabels,
ArrayRef<SourceLoc> argLabelLocs,
bool hasTrailingClosure, ConcreteDeclRef member,
bool implicit);
public:
/// Create a dynamic subscript.
///
/// Note: do not create new callers to this entry point; use the entry point
/// that takes separate index arguments.
static DynamicSubscriptExpr *create(
ASTContext &ctx, Expr *base, Expr *index, ConcreteDeclRef decl,
bool implicit,
llvm::function_ref<Type(Expr *)> getType = [](Expr *E) -> Type {
return E->getType();
});
/// getIndex - Retrieve the index of the subscript expression, i.e., the
/// "offset" into the base value.
Expr *getIndex() const { return Index; }
void setIndex(Expr *E) { Index = E; }
unsigned getNumArguments() const {
return Bits.DynamicSubscriptExpr.NumArgLabels;
}
bool hasArgumentLabelLocs() const {
return Bits.DynamicSubscriptExpr.HasArgLabelLocs;
}
/// Whether this call with written with a trailing closure.
bool hasTrailingClosure() const {
return Bits.DynamicSubscriptExpr.HasTrailingClosure;
}
/// Return the index of the unlabeled trailing closure argument.
Optional<unsigned> getUnlabeledTrailingClosureIndex() const {
return Index->getUnlabeledTrailingClosureIndexOfPackedArgument();
}
SourceLoc getLoc() const { return Index->getStartLoc(); }
SourceLoc getStartLoc() const { return getBase()->getStartLoc(); }
SourceLoc getEndLoc() const { return Index->getEndLoc(); }
static bool classof(const Expr *E) {
return E->getKind() == ExprKind::DynamicSubscript;
}
};
/// UnresolvedMemberExpr - This represents '.foo', an unresolved reference to a
/// member, which is to be resolved with context sensitive type information into
/// bar.foo. These always have unresolved type.
class UnresolvedMemberExpr final
: public Expr {
SourceLoc DotLoc;
DeclNameLoc NameLoc;
DeclNameRef Name;
public:
UnresolvedMemberExpr(SourceLoc dotLoc, DeclNameLoc nameLoc, DeclNameRef name,
bool implicit)
: Expr(ExprKind::UnresolvedMember, implicit), DotLoc(dotLoc),
NameLoc(nameLoc), Name(name) {
// FIXME: Really, we should be setting this to `FunctionRefKind::Compound`
// if `NameLoc` is compound, but this would be a source break for cases like
// ```
// struct S {
// static func makeS(_: Int) -> S! { S() }
// }
//
// let s: S = .makeS(_:)(0)
// ```
// Instead, we should store compound-ness as a separate bit from applied/
// unapplied.
Bits.UnresolvedMemberExpr.FunctionRefKind =
static_cast<unsigned>(FunctionRefKind::Unapplied);
}
DeclNameRef getName() const { return Name; }
DeclNameLoc getNameLoc() const { return NameLoc; }
SourceLoc getDotLoc() const { return DotLoc; }
SourceLoc getLoc() const { return NameLoc.getBaseNameLoc(); }
SourceLoc getStartLoc() const { return DotLoc; }
SourceLoc getEndLoc() const { return NameLoc.getSourceRange().End; }
/// Retrieve the kind of function reference.
FunctionRefKind getFunctionRefKind() const {
return static_cast<FunctionRefKind>(
Bits.UnresolvedMemberExpr.FunctionRefKind);
}
/// Set the kind of function reference.
void setFunctionRefKind(FunctionRefKind refKind) {
Bits.UnresolvedMemberExpr.FunctionRefKind = static_cast<unsigned>(refKind);
}
static bool classof(const Expr *E) {
return E->getKind() == ExprKind::UnresolvedMember;
}
};
/// AnyTryExpr - An abstract superclass for 'try' and 'try!'.
///
/// These are like IdentityExpr in some ways, but they're a bit too
/// semantic differentiated to just always look through.
class AnyTryExpr : public Expr {
Expr *SubExpr;
SourceLoc TryLoc;
public:
AnyTryExpr(ExprKind kind, SourceLoc tryLoc, Expr *sub,
Type type, bool implicit)
: Expr(kind, implicit, type), SubExpr(sub), TryLoc(tryLoc) {}
SourceLoc getLoc() const { return SubExpr->getLoc(); }
Expr *getSubExpr() const { return SubExpr; }
void setSubExpr(Expr *E) { SubExpr = E; }
SourceLoc getTryLoc() const { return TryLoc; }
SourceLoc getStartLoc() const { return TryLoc; }
SourceLoc getEndLoc() const { return getSubExpr()->getEndLoc(); }
static bool classof(const Expr *e) {
return e->getKind() >= ExprKind::First_AnyTryExpr
&& e->getKind() <= ExprKind::Last_AnyTryExpr;
}
};
/// TryExpr - A 'try' surrounding an expression, marking that the
/// expression contains code which might throw.
///
/// getSemanticsProvidingExpr() looks through this because it doesn't
/// provide the value and only very specific clients care where the
/// 'try' was written.
class TryExpr : public AnyTryExpr {
public:
TryExpr(SourceLoc tryLoc, Expr *sub, Type type = Type(),
bool implicit = false)
: AnyTryExpr(ExprKind::Try, tryLoc, sub, type, implicit) {}
static bool classof(const Expr *e) {
return e->getKind() == ExprKind::Try;
}
};
/// ForceTryExpr - A 'try!' surrounding an expression, marking that
/// the expression contains code which might throw, but that the code
/// should dynamically assert if it does.
class ForceTryExpr final : public AnyTryExpr {
SourceLoc ExclaimLoc;
public:
ForceTryExpr(SourceLoc tryLoc, Expr *sub, SourceLoc exclaimLoc,
Type type = Type(), bool implicit = false)
: AnyTryExpr(ExprKind::ForceTry, tryLoc, sub, type, implicit),
ExclaimLoc(exclaimLoc) {}
SourceLoc getExclaimLoc() const { return ExclaimLoc; }
static bool classof(const Expr *e) {
return e->getKind() == ExprKind::ForceTry;
}
};
/// A 'try?' surrounding an expression, marking that the expression contains
/// code which might throw, and that the result should be injected into an
/// Optional. If the code does throw, \c nil is produced.
class OptionalTryExpr final : public AnyTryExpr {
SourceLoc QuestionLoc;
public:
OptionalTryExpr(SourceLoc tryLoc, Expr *sub, SourceLoc questionLoc,
Type type = Type(), bool implicit = false)
: AnyTryExpr(ExprKind::OptionalTry, tryLoc, sub, type, implicit),
QuestionLoc(questionLoc) {}
SourceLoc getQuestionLoc() const { return QuestionLoc; }
static bool classof(const Expr *e) {
return e->getKind() == ExprKind::OptionalTry;
}
};
/// An expression node that does not affect the evaluation of its subexpression.
class IdentityExpr : public Expr {
Expr *SubExpr;
public:
IdentityExpr(ExprKind kind,
Expr *subExpr, Type ty = Type(),
bool implicit = false)
: Expr(kind, implicit, ty), SubExpr(subExpr)
{}
SourceLoc getLoc() const { return SubExpr->getLoc(); }
Expr *getSubExpr() const { return SubExpr; }
void setSubExpr(Expr *E) { SubExpr = E; }
static bool classof(const Expr *E) {
return E->getKind() >= ExprKind::First_IdentityExpr
&& E->getKind() <= ExprKind::Last_IdentityExpr;
}
};
/// The '.self' pseudo-property, which has no effect except to
/// satisfy the syntactic requirement that type values appear only as part of
/// a property chain.
class DotSelfExpr : public IdentityExpr {
SourceLoc DotLoc;
SourceLoc SelfLoc;
public:
DotSelfExpr(Expr *subExpr, SourceLoc dot, SourceLoc self,
Type ty = Type())
: IdentityExpr(ExprKind::DotSelf, subExpr, ty),
DotLoc(dot), SelfLoc(self)
{}
SourceLoc getDotLoc() const { return DotLoc; }
SourceLoc getSelfLoc() const { return SelfLoc; }
SourceLoc getStartLoc() const { return getSubExpr()->getStartLoc(); }
SourceLoc getEndLoc() const { return SelfLoc; }
static bool classof(const Expr *E) {
return E->getKind() == ExprKind::DotSelf;
}
};
/// A parenthesized expression like '(x+x)'. Syntactically,
/// this is just a TupleExpr with exactly one element that has no label.
/// Semantically, however, it serves only as grouping parentheses and
/// does not form an expression of tuple type (unless the sub-expression
/// has tuple type, of course).
class ParenExpr : public IdentityExpr {
SourceLoc LParenLoc, RParenLoc;
public:
ParenExpr(SourceLoc lploc, Expr *subExpr, SourceLoc rploc,
bool hasTrailingClosure,
Type ty = Type())
: IdentityExpr(ExprKind::Paren, subExpr, ty),
LParenLoc(lploc), RParenLoc(rploc) {
Bits.ParenExpr.HasTrailingClosure = hasTrailingClosure;
assert(lploc.isValid() == rploc.isValid() &&
"Mismatched source location information");
}
SourceLoc getLParenLoc() const { return LParenLoc; }
SourceLoc getRParenLoc() const { return RParenLoc; }
// When the locations of the parens are invalid, ask our
// subexpression for its source range instead. This isn't a
// hot path and so we don't both optimizing for it.
SourceLoc getStartLoc() const {
return (LParenLoc.isInvalid() ? getSubExpr()->getStartLoc() : LParenLoc);
}
SourceLoc getEndLoc() const {
// If we have a trailing closure, our end point is the end of the
// trailing closure.
if (RParenLoc.isInvalid() || Bits.ParenExpr.HasTrailingClosure)
return getSubExpr()->getEndLoc();
return RParenLoc;
}
/// Whether this expression has a trailing closure as its argument.
bool hasTrailingClosure() const { return Bits.ParenExpr.HasTrailingClosure; }
Optional<unsigned>
getUnlabeledTrailingClosureIndexOfPackedArgument() const {
return hasTrailingClosure() ? Optional<unsigned>(0) : None;
}
static bool classof(const Expr *E) { return E->getKind() == ExprKind::Paren; }
};
/// Represents the result of a chain of accesses or calls hanging off of an
/// \c UnresolvedMemberExpr at the root. This is only used during type checking
/// to give the result type of such a chain representation in the AST. This
/// expression type is always implicit.
class UnresolvedMemberChainResultExpr : public IdentityExpr {
/// The base of this chain of member accesses.
UnresolvedMemberExpr *ChainBase;
public:
UnresolvedMemberChainResultExpr(Expr *subExpr, UnresolvedMemberExpr *base,
Type ty = Type())
: IdentityExpr(ExprKind::UnresolvedMemberChainResult, subExpr, ty,
/*isImplicit=*/true),
ChainBase(base) {
assert(base);
}
UnresolvedMemberExpr *getChainBase() const { return ChainBase; }
SWIFT_FORWARD_SOURCE_LOCS_TO(getSubExpr())
static bool classof(const Expr *E) {
return E->getKind() == ExprKind::UnresolvedMemberChainResult;
}
};
/// AwaitExpr - An 'await' surrounding an expression, marking that the
/// expression contains code which is a coroutine that may block.
///
/// getSemanticsProvidingExpr() looks through this because it doesn't
/// provide the value and only very specific clients care where the
/// 'await' was written.
class AwaitExpr final : public IdentityExpr {
SourceLoc AwaitLoc;
public:
AwaitExpr(SourceLoc awaitLoc, Expr *sub, Type type = Type(),
bool implicit = false)
: IdentityExpr(ExprKind::Await, sub, type, implicit), AwaitLoc(awaitLoc) {
}
SourceLoc getLoc() const { return AwaitLoc; }
SourceLoc getAwaitLoc() const { return AwaitLoc; }
SourceLoc getStartLoc() const { return AwaitLoc; }
SourceLoc getEndLoc() const { return getSubExpr()->getEndLoc(); }
static bool classof(const Expr *e) {
return e->getKind() == ExprKind::Await;
}
};
/// TupleExpr - Parenthesized expressions like '(a: x+x)' and '(x, y, 4)'. Also
/// used to represent the operands to a binary operator. Note that
/// expressions like '(4)' are represented with a ParenExpr.
class TupleExpr final : public Expr,
private llvm::TrailingObjects<TupleExpr, Expr *, Identifier, SourceLoc> {
friend TrailingObjects;
SourceLoc LParenLoc;
SourceLoc RParenLoc;
Optional<unsigned> FirstTrailingArgumentAt;
size_t numTrailingObjects(OverloadToken<Expr *>) const {
return getNumElements();
}
size_t numTrailingObjects(OverloadToken<Identifier>) const {
return hasElementNames() ? getNumElements() : 0;
}
size_t numTrailingObjects(OverloadToken<SourceLoc>) const {
return hasElementNames() ? getNumElements() : 0;
}
/// Retrieve the buffer containing the element names.
MutableArrayRef<Identifier> getElementNamesBuffer() {
if (!hasElementNames())
return { };
return { getTrailingObjects<Identifier>(), getNumElements() };
}
/// Retrieve the buffer containing the element name locations.
MutableArrayRef<SourceLoc> getElementNameLocsBuffer() {
if (!hasElementNameLocs())
return { };
return { getTrailingObjects<SourceLoc>(), getNumElements() };
}
TupleExpr(SourceLoc LParenLoc, SourceLoc RParenLoc,
ArrayRef<Expr *> SubExprs,
ArrayRef<Identifier> ElementNames,
ArrayRef<SourceLoc> ElementNameLocs,
Optional<unsigned> FirstTrailingArgumentAt, bool Implicit, Type Ty);
public:
/// Create a tuple.
static TupleExpr *create(ASTContext &ctx,
SourceLoc LParenLoc,
ArrayRef<Expr *> SubExprs,
ArrayRef<Identifier> ElementNames,
ArrayRef<SourceLoc> ElementNameLocs,
SourceLoc RParenLoc, bool HasTrailingClosure,
bool Implicit, Type Ty = Type());
static TupleExpr *create(ASTContext &ctx,
SourceLoc LParenLoc,
SourceLoc RParenLoc,
ArrayRef<Expr *> SubExprs,
ArrayRef<Identifier> ElementNames,
ArrayRef<SourceLoc> ElementNameLocs,
Optional<unsigned> FirstTrailingArgumentAt,
bool Implicit, Type Ty = Type());
/// Create an empty tuple.
static TupleExpr *createEmpty(ASTContext &ctx, SourceLoc LParenLoc,
SourceLoc RParenLoc, bool Implicit);
/// Create an implicit tuple with no source information.
static TupleExpr *createImplicit(ASTContext &ctx, ArrayRef<Expr *> SubExprs,
ArrayRef<Identifier> ElementNames);
SourceLoc getLParenLoc() const { return LParenLoc; }
SourceLoc getRParenLoc() const { return RParenLoc; }
SourceRange getSourceRange() const;
bool hasAnyTrailingClosures() const {
return (bool) FirstTrailingArgumentAt;
}
/// Whether this expression has a trailing closure as its argument.
bool hasTrailingClosure() const {
return FirstTrailingArgumentAt
? *FirstTrailingArgumentAt == getNumElements() - 1
: false;
}
bool hasMultipleTrailingClosures() const {
return FirstTrailingArgumentAt ? !hasTrailingClosure() : false;
}
Optional<unsigned>
getUnlabeledTrailingClosureIndexOfPackedArgument() const {
return FirstTrailingArgumentAt;
}
/// Retrieve the elements of this tuple.
MutableArrayRef<Expr*> getElements() {
return { getTrailingObjects<Expr *>(), getNumElements() };
}
/// Retrieve the elements of this tuple.
ArrayRef<Expr*> getElements() const {
return { getTrailingObjects<Expr *>(), getNumElements() };
}
MutableArrayRef<Expr*> getTrailingElements() {
return getElements().take_back(getNumTrailingElements());
}
ArrayRef<Expr*> getTrailingElements() const {
return getElements().take_back(getNumTrailingElements());
}
unsigned getNumElements() const { return Bits.TupleExpr.NumElements; }
unsigned getNumTrailingElements() const {
return FirstTrailingArgumentAt
? getNumElements() - *FirstTrailingArgumentAt
: 0;
}
Expr *getElement(unsigned i) const {
return getElements()[i];
}
void setElement(unsigned i, Expr *e) {
getElements()[i] = e;
}
/// Whether this tuple has element names.
bool hasElementNames() const {
return Bits.TupleExpr.HasElementNames;
}
/// Retrieve the element names for a tuple.
ArrayRef<Identifier> getElementNames() const {
return const_cast<TupleExpr *>(this)->getElementNamesBuffer();
}
/// Retrieve the ith element name.
Identifier getElementName(unsigned i) const {
return hasElementNames() ? getElementNames()[i] : Identifier();
}
/// Whether this tuple has element name locations.
bool hasElementNameLocs() const {
return Bits.TupleExpr.HasElementNameLocations;
}
/// Retrieve the locations of the element names for a tuple.
ArrayRef<SourceLoc> getElementNameLocs() const {
return const_cast<TupleExpr *>(this)->getElementNameLocsBuffer();
}
/// Retrieve the location of the ith label, if known.
SourceLoc getElementNameLoc(unsigned i) const {
if (hasElementNameLocs())
return getElementNameLocs()[i];
return SourceLoc();
}
static bool classof(const Expr *E) { return E->getKind() == ExprKind::Tuple; }
};
/// A collection literal expression.
///
/// The subexpression is represented as a TupleExpr or ParenExpr and
/// passed on to the appropriate semantics-providing conversion
/// operation.
class CollectionExpr : public Expr {
SourceLoc LBracketLoc;
SourceLoc RBracketLoc;
ConcreteDeclRef Initializer;
/// Retrieve the intrusive pointer storage from the subtype
Expr *const *getTrailingObjectsPointer() const;
Expr **getTrailingObjectsPointer() {
const CollectionExpr *temp = this;
return const_cast<Expr**>(temp->getTrailingObjectsPointer());
}
/// Retrieve the intrusive pointer storage from the subtype
const SourceLoc *getTrailingSourceLocs() const;
SourceLoc *getTrailingSourceLocs() {
const CollectionExpr *temp = this;
return const_cast<SourceLoc*>(temp->getTrailingSourceLocs());
}
protected:
CollectionExpr(ExprKind Kind, SourceLoc LBracketLoc,
ArrayRef<Expr*> Elements, ArrayRef<SourceLoc> CommaLocs,
SourceLoc RBracketLoc, Type Ty)
: Expr(Kind, /*Implicit=*/false, Ty),
LBracketLoc(LBracketLoc), RBracketLoc(RBracketLoc) {
Bits.CollectionExpr.IsTypeDefaulted = false;
Bits.CollectionExpr.NumSubExprs = Elements.size();
Bits.CollectionExpr.NumCommas = CommaLocs.size();
assert(Bits.CollectionExpr.NumCommas == CommaLocs.size() && "Truncation");
std::uninitialized_copy(Elements.begin(), Elements.end(),
getTrailingObjectsPointer());
std::uninitialized_copy(CommaLocs.begin(), CommaLocs.end(),
getTrailingSourceLocs());
}
public:
/// Retrieve the elements stored in the collection.
ArrayRef<Expr *> getElements() const {
return {getTrailingObjectsPointer(), Bits.CollectionExpr.NumSubExprs};
}
MutableArrayRef<Expr *> getElements() {
return {getTrailingObjectsPointer(), Bits.CollectionExpr.NumSubExprs};
}
Expr *getElement(unsigned i) const { return getElements()[i]; }
void setElement(unsigned i, Expr *E) { getElements()[i] = E; }
unsigned getNumElements() const { return Bits.CollectionExpr.NumSubExprs; }
/// Retrieve the comma source locations stored in the collection. Please note
/// that trailing commas are currently allowed, and that invalid code may have
/// stray or missing commas.
MutableArrayRef<SourceLoc> getCommaLocs() {
return {getTrailingSourceLocs(), static_cast<size_t>(Bits.CollectionExpr.NumCommas)};
}
ArrayRef<SourceLoc> getCommaLocs() const {
return {getTrailingSourceLocs(), static_cast<size_t>(Bits.CollectionExpr.NumCommas)};
}
unsigned getNumCommas() const { return Bits.CollectionExpr.NumCommas; }
bool isTypeDefaulted() const { return Bits.CollectionExpr.IsTypeDefaulted; }
void setIsTypeDefaulted(bool value = true) {
Bits.CollectionExpr.IsTypeDefaulted = value;
}
SourceLoc getLBracketLoc() const { return LBracketLoc; }
SourceLoc getRBracketLoc() const { return RBracketLoc; }
SourceRange getSourceRange() const {
return SourceRange(LBracketLoc, RBracketLoc);
}
static bool classof(const Expr *e) {
return e->getKind() >= ExprKind::First_CollectionExpr &&
e->getKind() <= ExprKind::Last_CollectionExpr;
}
/// Retrieve the initializer that will be used to construct the 'array'
/// literal from the result of the initializer.
ConcreteDeclRef getInitializer() const { return Initializer; }
/// Set the initializer that will be used to construct the 'array' literal.
void setInitializer(ConcreteDeclRef initializer) {
Initializer = initializer;
}
};
/// An array literal expression [a, b, c].
class ArrayExpr final : public CollectionExpr,
private llvm::TrailingObjects<ArrayExpr, Expr*, SourceLoc> {
friend TrailingObjects;
friend CollectionExpr;
size_t numTrailingObjects(OverloadToken<Expr *>) const {
return getNumElements();
}
size_t numTrailingObjects(OverloadToken<SourceLoc>) const {
return getNumCommas();
}
ArrayExpr(SourceLoc LBracketLoc, ArrayRef<Expr*> Elements,
ArrayRef<SourceLoc> CommaLocs,
SourceLoc RBracketLoc, Type Ty)
: CollectionExpr(ExprKind::Array, LBracketLoc, Elements, CommaLocs,
RBracketLoc, Ty) { }
public:
static ArrayExpr *create(ASTContext &C, SourceLoc LBracketLoc,
ArrayRef<Expr*> Elements,
ArrayRef<SourceLoc> CommaLocs,
SourceLoc RBracketLoc,
Type Ty = Type());
static bool classof(const Expr *e) {
return e->getKind() == ExprKind::Array;
}
Type getElementType();
};
/// A dictionary literal expression [a : x, b : y, c : z].
class DictionaryExpr final : public CollectionExpr,
private llvm::TrailingObjects<DictionaryExpr, Expr*, SourceLoc> {
friend TrailingObjects;
friend CollectionExpr;
size_t numTrailingObjects(OverloadToken<Expr *>) const {
return getNumElements();
}
size_t numTrailingObjects(OverloadToken<SourceLoc>) const {
return getNumCommas();
}
DictionaryExpr(SourceLoc LBracketLoc, ArrayRef<Expr*> Elements,
ArrayRef<SourceLoc> CommaLocs,
SourceLoc RBracketLoc, Type Ty)
: CollectionExpr(ExprKind::Dictionary, LBracketLoc, Elements, CommaLocs,
RBracketLoc, Ty) { }
public:
static DictionaryExpr *create(ASTContext &C, SourceLoc LBracketLoc,
ArrayRef<Expr*> Elements,
ArrayRef<SourceLoc> CommaLocs,
SourceLoc RBracketLoc,
Type Ty = Type());
static bool classof(const Expr *e) {
return e->getKind() == ExprKind::Dictionary;
}
Type getElementType();
};
/// Subscripting expressions like a[i] that refer to an element within a
/// container.
///
/// There is no built-in subscripting in the language. Rather, a fully
/// type-checked and well-formed subscript expression refers to a subscript
/// declaration, which provides a getter and (optionally) a setter that will
/// be used to perform reads/writes.
class SubscriptExpr final : public LookupExpr,
public TrailingCallArguments<SubscriptExpr> {
friend TrailingCallArguments;
Expr *Index;
SubscriptExpr(Expr *base, Expr *index, ArrayRef<Identifier> argLabels,
ArrayRef<SourceLoc> argLabelLocs, bool hasTrailingClosure,
ConcreteDeclRef decl, bool implicit, AccessSemantics semantics);
public:
/// Create a subscript.
///
/// Note: do not create new callers to this entry point; use the entry point
/// that takes separate index arguments.
static SubscriptExpr *create(
ASTContext &ctx, Expr *base, Expr *index,
ConcreteDeclRef decl = ConcreteDeclRef(), bool implicit = false,
AccessSemantics semantics = AccessSemantics::Ordinary,
llvm::function_ref<Type(Expr *)> getType = [](Expr *E) -> Type {
return E->getType();
});
/// Create a new subscript.
static SubscriptExpr *create(ASTContext &ctx, Expr *base,
SourceLoc lSquareLoc,
ArrayRef<Expr *> indexArgs,
ArrayRef<Identifier> indexArgLabels,
ArrayRef<SourceLoc> indexArgLabelLocs,
SourceLoc rSquareLoc,
ArrayRef<TrailingClosure> trailingClosures,
ConcreteDeclRef decl = ConcreteDeclRef(),
bool implicit = false,
AccessSemantics semantics
= AccessSemantics::Ordinary);
/// getIndex - Retrieve the index of the subscript expression, i.e., the
/// "offset" into the base value.
Expr *getIndex() const { return Index; }
void setIndex(Expr *E) { Index = E; }
unsigned getNumArguments() const {
return Bits.SubscriptExpr.NumArgLabels;
}
bool hasArgumentLabelLocs() const {
return Bits.SubscriptExpr.HasArgLabelLocs;
}
/// Whether this call was written with a trailing closure.
bool hasTrailingClosure() const {
return Bits.SubscriptExpr.HasTrailingClosure;
}
/// Return the index of the unlabeled trailing closure argument.
Optional<unsigned> getUnlabeledTrailingClosureIndex() const {
return getIndex()->getUnlabeledTrailingClosureIndexOfPackedArgument();
}
/// Determine whether this subscript reference should bypass the
/// ordinary accessors.
AccessSemantics getAccessSemantics() const {
return (AccessSemantics) Bits.SubscriptExpr.Semantics;
}
SourceLoc getLoc() const { return Index->getStartLoc(); }
SourceLoc getStartLoc() const { return getBase()->getStartLoc(); }
SourceLoc getEndLoc() const {
auto end = Index->getEndLoc();
return end.isValid() ? end : getBase()->getEndLoc();
}
static bool classof(const Expr *E) {
return E->getKind() == ExprKind::Subscript;
}
};
/// Subscripting expression that applies a keypath to a base.
class KeyPathApplicationExpr : public Expr {
Expr *Base;
Expr *KeyPath;
SourceLoc LBracketLoc, RBracketLoc;
public:
KeyPathApplicationExpr(Expr *base, SourceLoc lBracket, Expr *keyPath,
SourceLoc rBracket, Type ty, bool implicit)
: Expr(ExprKind::KeyPathApplication, implicit, ty),
Base(base), KeyPath(keyPath), LBracketLoc(lBracket), RBracketLoc(rBracket)
{}
SourceLoc getLoc() const { return LBracketLoc; }
SourceLoc getStartLoc() const { return Base->getStartLoc(); }
SourceLoc getEndLoc() const { return RBracketLoc; }
Expr *getBase() const { return Base; }
void setBase(Expr *E) { Base = E; }
Expr *getKeyPath() const { return KeyPath; }
void setKeyPath(Expr *E) { KeyPath = E; }
static bool classof(const Expr *E) {
return E->getKind() == ExprKind::KeyPathApplication;
}
};
/// A member access (foo.bar) on an expression with unresolved type.
class UnresolvedDotExpr : public Expr {
Expr *SubExpr;
SourceLoc DotLoc;
DeclNameLoc NameLoc;
DeclNameRef Name;
ArrayRef<ValueDecl *> OuterAlternatives;
public:
UnresolvedDotExpr(
Expr *subexpr, SourceLoc dotloc, DeclNameRef name, DeclNameLoc nameloc,
bool Implicit,
ArrayRef<ValueDecl *> outerAlternatives = ArrayRef<ValueDecl *>())
: Expr(ExprKind::UnresolvedDot, Implicit), SubExpr(subexpr),
DotLoc(dotloc), NameLoc(nameloc), Name(name),
OuterAlternatives(outerAlternatives) {
Bits.UnresolvedDotExpr.FunctionRefKind =
static_cast<unsigned>(NameLoc.isCompound() ? FunctionRefKind::Compound
: FunctionRefKind::Unapplied);
}
static UnresolvedDotExpr *createImplicit(
ASTContext &C, Expr *base, DeclName name) {
return new (C) UnresolvedDotExpr(base, SourceLoc(),
DeclNameRef(name), DeclNameLoc(),
/*implicit=*/true);
}
static UnresolvedDotExpr *createImplicit(
ASTContext &C, Expr *base,
DeclBaseName baseName, ArrayRef<Identifier> argLabels) {
return UnresolvedDotExpr::createImplicit(C, base,
DeclName(C, baseName, argLabels));
}
static UnresolvedDotExpr *createImplicit(
ASTContext &C, Expr *base,
DeclBaseName baseName, ParameterList *paramList) {
return UnresolvedDotExpr::createImplicit(C, base,
DeclName(C, baseName, paramList));
}
SourceLoc getLoc() const {
if (NameLoc.isValid())
return NameLoc.getBaseNameLoc();
else if (DotLoc.isValid())
return DotLoc;
else
return SubExpr->getEndLoc();
}
SourceLoc getStartLoc() const {
auto SubLoc = SubExpr->getStartLoc();
if (SubLoc.isValid())
return SubLoc;
else if (DotLoc.isValid())
return DotLoc;
else
return NameLoc.getSourceRange().Start;
}
SourceLoc getEndLoc() const {
if (NameLoc.isValid())
return NameLoc.getSourceRange().End;
else if (DotLoc.isValid())
return DotLoc;
else
return SubExpr->getEndLoc();
}
SourceLoc getDotLoc() const { return DotLoc; }
Expr *getBase() const { return SubExpr; }
void setBase(Expr *e) { SubExpr = e; }
DeclNameRef getName() const { return Name; }
DeclNameLoc getNameLoc() const { return NameLoc; }
ArrayRef<ValueDecl *> getOuterAlternatives() const {
return OuterAlternatives;
}
/// Retrieve the kind of function reference.
FunctionRefKind getFunctionRefKind() const {
return static_cast<FunctionRefKind>(Bits.UnresolvedDotExpr.FunctionRefKind);
}
/// Set the kind of function reference.
void setFunctionRefKind(FunctionRefKind refKind) {
Bits.UnresolvedDotExpr.FunctionRefKind = static_cast<unsigned>(refKind);
}
static bool classof(const Expr *E) {
return E->getKind() == ExprKind::UnresolvedDot;
}
};
/// TupleElementExpr - Refer to an element of a tuple,
/// e.g. "(1,field:2).field".
class TupleElementExpr : public Expr {
Expr *SubExpr;
SourceLoc NameLoc;
SourceLoc DotLoc;
public:
TupleElementExpr(Expr *SubExpr, SourceLoc DotLoc, unsigned FieldNo,
SourceLoc NameLoc, Type Ty)
: Expr(ExprKind::TupleElement, /*Implicit=*/false, Ty), SubExpr(SubExpr),
NameLoc(NameLoc), DotLoc(DotLoc) {
Bits.TupleElementExpr.FieldNo = FieldNo;
}
SourceLoc getLoc() const { return NameLoc; }
Expr *getBase() const { return SubExpr; }
void setBase(Expr *e) { SubExpr = e; }
unsigned getFieldNumber() const { return Bits.TupleElementExpr.FieldNo; }
SourceLoc getNameLoc() const { return NameLoc; }
SourceLoc getDotLoc() const { return DotLoc; }
SourceLoc getStartLoc() const { return getBase()->getStartLoc(); }
SourceLoc getEndLoc() const { return getNameLoc(); }
static bool classof(const Expr *E) {
return E->getKind() == ExprKind::TupleElement;
}
};
/// Describes a monadic bind from T? to T.
///
/// In a ?-chain expression, this is the part that's spelled with a
/// postfix ?.
///
/// A BindOptionalExpr must always appear within a
/// OptionalEvaluationExpr. If the operand of the BindOptionalExpr
/// evaluates to a missing value, the OptionalEvaluationExpr
/// immediately completes and produces a missing value in the result
/// type.
///
/// The depth of the BindOptionalExpr indicates which
/// OptionalEvaluationExpr is completed, in case the BindOptionalExpr
/// is contained within more than one such expression.
class BindOptionalExpr : public Expr {
Expr *SubExpr;
SourceLoc QuestionLoc;
public:
BindOptionalExpr(Expr *subExpr, SourceLoc questionLoc,
unsigned depth, Type ty = Type())
: Expr(ExprKind::BindOptional, /*Implicit=*/ questionLoc.isInvalid(), ty),
SubExpr(subExpr), QuestionLoc(questionLoc) {
Bits.BindOptionalExpr.Depth = depth;
assert(Bits.BindOptionalExpr.Depth == depth && "bitfield truncation");
}
SourceRange getSourceRange() const {
if (QuestionLoc.isInvalid())
return SubExpr->getSourceRange();
return SourceRange(SubExpr->getStartLoc(), QuestionLoc);
}
SourceLoc getStartLoc() const {
return SubExpr->getStartLoc();
}
SourceLoc getEndLoc() const {
return (QuestionLoc.isInvalid() ? SubExpr->getEndLoc() : QuestionLoc);
}
SourceLoc getLoc() const {
if (isImplicit())
return SubExpr->getLoc();
return getQuestionLoc();
}
SourceLoc getQuestionLoc() const { return QuestionLoc; }
unsigned getDepth() const { return Bits.BindOptionalExpr.Depth; }
void setDepth(unsigned depth) {
Bits.BindOptionalExpr.Depth = depth;
}
Expr *getSubExpr() const { return SubExpr; }
void setSubExpr(Expr *expr) { SubExpr = expr; }
static bool classof(const Expr *E) {
return E->getKind() == ExprKind::BindOptional;
}
};
/// Describes the outer limits of an operation containing
/// monadic binds of T? to T.
///
/// In a ?-chain expression, this is implicitly formed at the outer
/// limits of the chain. For example, in (foo?.bar?().baz).fred,
/// this is nested immediately within the parens.
///
/// This expression will always have optional type.
class OptionalEvaluationExpr : public Expr {
Expr *SubExpr;
public:
OptionalEvaluationExpr(Expr *subExpr, Type ty = Type())
: Expr(ExprKind::OptionalEvaluation, /*Implicit=*/ true, ty),
SubExpr(subExpr) {}
SWIFT_FORWARD_SOURCE_LOCS_TO(SubExpr)
Expr *getSubExpr() const { return SubExpr; }
void setSubExpr(Expr *expr) { SubExpr = expr; }
static bool classof(const Expr *E) {
return E->getKind() == ExprKind::OptionalEvaluation;
}
};
/// An expression that forces an optional to its underlying value.
///
/// \code
/// func parseInt(s : String) -> Int? { ... }
///
/// var maybeInt = parseInt("5") // returns an Int?
/// var forcedInt = parseInt("5")! // returns an Int; fails on empty optional
/// \endcode
///
class ForceValueExpr : public Expr {
Expr *SubExpr;
SourceLoc ExclaimLoc;
public:
ForceValueExpr(Expr *subExpr, SourceLoc exclaimLoc, bool forcedIUO = false)
: Expr(ExprKind::ForceValue, /*Implicit=*/exclaimLoc.isInvalid(), Type()),
SubExpr(subExpr), ExclaimLoc(exclaimLoc) {
Bits.ForceValueExpr.ForcedIUO = forcedIUO;
}
SourceRange getSourceRange() const {
if (ExclaimLoc.isInvalid())
return SubExpr->getSourceRange();
return SourceRange(SubExpr->getStartLoc(), ExclaimLoc);
}
SourceLoc getStartLoc() const {
return SubExpr->getStartLoc();
}
SourceLoc getEndLoc() const {
return (isImplicit() ? SubExpr->getEndLoc() : getExclaimLoc());
}
SourceLoc getLoc() const {
if (!isImplicit())
return getExclaimLoc();
return SubExpr->getLoc();
}
SourceLoc getExclaimLoc() const { return ExclaimLoc; }
Expr *getSubExpr() const { return SubExpr; }
void setSubExpr(Expr *expr) { SubExpr = expr; }
bool isForceOfImplicitlyUnwrappedOptional() const {
return Bits.ForceValueExpr.ForcedIUO;
}
static bool classof(const Expr *E) {
return E->getKind() == ExprKind::ForceValue;
}
};
/// An expression that grants temporary escapability to a nonescaping
/// closure value.
///
/// This expression is formed by the type checker when a call to the
/// `withoutActuallyEscaping` declaration is made.
class MakeTemporarilyEscapableExpr : public Expr {
Expr *NonescapingClosureValue;
OpaqueValueExpr *EscapingClosureValue;
Expr *SubExpr;
SourceLoc NameLoc, LParenLoc, RParenLoc;
Expr *OriginalExpr;
public:
MakeTemporarilyEscapableExpr(SourceLoc NameLoc,
SourceLoc LParenLoc,
Expr *NonescapingClosureValue,
Expr *SubExpr,
SourceLoc RParenLoc,
OpaqueValueExpr *OpaqueValueForEscapingClosure,
Expr *OriginalExpr,
bool implicit = false)
: Expr(ExprKind::MakeTemporarilyEscapable, implicit, Type()),
NonescapingClosureValue(NonescapingClosureValue),
EscapingClosureValue(OpaqueValueForEscapingClosure),
SubExpr(SubExpr),
NameLoc(NameLoc), LParenLoc(LParenLoc), RParenLoc(RParenLoc),
OriginalExpr(OriginalExpr)
{}
SourceLoc getStartLoc() const {
return NameLoc;
}
SourceLoc getEndLoc() const {
return RParenLoc;
}
SourceLoc getLoc() const {
return NameLoc;
}
/// Retrieve the opaque value representing the escapable copy of the
/// closure.
OpaqueValueExpr *getOpaqueValue() const { return EscapingClosureValue; }
/// Retrieve the nonescaping closure expression.
Expr *getNonescapingClosureValue() const {
return NonescapingClosureValue;
}
void setNonescapingClosureValue(Expr *e) {
NonescapingClosureValue = e;
}
/// Retrieve the subexpression that has access to the escapable copy of the
/// closure.
Expr *getSubExpr() const {
return SubExpr;
}
void setSubExpr(Expr *e) {
SubExpr = e;
}
/// Retrieve the original 'withoutActuallyEscaping(closure) { ... }'
// expression.
Expr *getOriginalExpr() const {
return OriginalExpr;
}
static bool classof(const Expr *E) {
return E->getKind() == ExprKind::MakeTemporarilyEscapable;
}
};
/// An expression that opens up a value of protocol or protocol
/// composition type and gives a name to its dynamic type.
///
/// This expression is implicitly created by the type checker when
/// calling a method on a protocol. In the future, this may become an
/// actual operation within the language.
class OpenExistentialExpr : public Expr {
Expr *ExistentialValue;
OpaqueValueExpr *OpaqueValue;
Expr *SubExpr;
SourceLoc ExclaimLoc;
public:
OpenExistentialExpr(Expr *existentialValue,
OpaqueValueExpr *opaqueValue,
Expr *subExpr,
Type subExprTy)
: Expr(ExprKind::OpenExistential, /*Implicit=*/ true, subExprTy),
ExistentialValue(existentialValue), OpaqueValue(opaqueValue),
SubExpr(subExpr) { }
SWIFT_FORWARD_SOURCE_LOCS_TO(SubExpr)
/// Retrieve the expression that is being evaluated using the
/// archetype value.
///
/// This subexpression (and no other) may refer to the archetype
/// type or the opaque value that stores the archetype's value.
Expr *getSubExpr() const { return SubExpr; }
/// Set the subexpression that is being evaluated.
void setSubExpr(Expr *expr) { SubExpr = expr; }
/// Retrieve the existential value that is being opened.
Expr *getExistentialValue() const { return ExistentialValue; }
/// Set the existential val ue that is being opened.
void setExistentialValue(Expr *expr) { ExistentialValue = expr; }
/// Retrieve the opaque value representing the value (of archetype
/// type) stored in the existential.
OpaqueValueExpr *getOpaqueValue() const { return OpaqueValue; }
/// Retrieve the opened archetype, which can only be referenced
/// within this expression's subexpression.
OpenedArchetypeType *getOpenedArchetype() const;
static bool classof(const Expr *E) {
return E->getKind() == ExprKind::OpenExistential;
}
};
/// ImplicitConversionExpr - An abstract class for expressions which
/// implicitly convert the value of an expression in some way.
class ImplicitConversionExpr : public Expr {
Expr *SubExpr;
protected:
ImplicitConversionExpr(ExprKind kind, Expr *subExpr, Type ty)
: Expr(kind, /*Implicit=*/true, ty), SubExpr(subExpr) {}
public:
SWIFT_FORWARD_SOURCE_LOCS_TO(SubExpr)
Expr *getSubExpr() const { return SubExpr; }
void setSubExpr(Expr *e) { SubExpr = e; }
Expr *getSyntacticSubExpr() const {
if (auto *ICE = dyn_cast<ImplicitConversionExpr>(SubExpr))
return ICE->getSyntacticSubExpr();
return SubExpr;
}
static bool classof(const Expr *E) {
return E->getKind() >= ExprKind::First_ImplicitConversionExpr &&
E->getKind() <= ExprKind::Last_ImplicitConversionExpr;
}
};
/// The implicit conversion from a class metatype to AnyObject.
class ClassMetatypeToObjectExpr : public ImplicitConversionExpr {
public:
ClassMetatypeToObjectExpr(Expr *subExpr, Type ty)