@@ -303,6 +303,19 @@ class alignas(8) Expr {
303
303
NumVariadicArgs : 16
304
304
);
305
305
306
+ SWIFT_INLINE_BITFIELD_FULL (ArgumentShuffleExpr, ImplicitConversionExpr, 2 +16 +16 +16 ,
307
+ TypeImpact : 2 ,
308
+ : NumPadBits,
309
+ NumCallerDefaultArgs : 16 ,
310
+ // / This contains an entry for each element in the Expr type. Each element
311
+ // / specifies which index from the SubExpr that the destination element gets.
312
+ // / If the element value is DefaultInitialize, then the destination value
313
+ // / gets the default initializer for that tuple element value.
314
+ NumElementMappings : 16 ,
315
+ // / The arguments that are packed into the variadic element.
316
+ NumVariadicArgs : 16
317
+ );
318
+
306
319
SWIFT_INLINE_BITFIELD (ForceValueExpr, Expr, 1 ,
307
320
ForcedIUO : 1
308
321
);
@@ -3098,6 +3111,157 @@ class TupleShuffleExpr final : public ImplicitConversionExpr,
3098
3111
}
3099
3112
};
3100
3113
3114
+ // / ArgumentShuffleExpr - This represents a "complex" argument list of an
3115
+ // / ApplyExpr, with default arguments or varargs.
3116
+ // /
3117
+ // / If hasScalarSource() is true, the subexpression should be treated
3118
+ // / as if it were implicitly injected into a single-element tuple
3119
+ // / type. Otherwise, the subexpression is known to have a tuple type.
3120
+ class ArgumentShuffleExpr final : public ImplicitConversionExpr,
3121
+ private llvm::TrailingObjects<ArgumentShuffleExpr, Expr *, int , unsigned > {
3122
+ friend TrailingObjects;
3123
+
3124
+ size_t numTrailingObjects (OverloadToken<Expr *>) const {
3125
+ return Bits.ArgumentShuffleExpr .NumCallerDefaultArgs ;
3126
+ }
3127
+ size_t numTrailingObjects (OverloadToken<int >) const {
3128
+ return Bits.ArgumentShuffleExpr .NumElementMappings ;
3129
+ }
3130
+ size_t numTrailingObjects (OverloadToken<unsigned >) const {
3131
+ return Bits.ArgumentShuffleExpr .NumVariadicArgs ;
3132
+ }
3133
+
3134
+ public:
3135
+ enum : int {
3136
+ // / The element mapping value indicating that a field of the destination
3137
+ // / tuple should be default-initialized.
3138
+ DefaultInitialize = -1 ,
3139
+ // / The element mapping is part of the variadic field.
3140
+ Variadic = -2 ,
3141
+ // / The element mapping value indicating that the field of the
3142
+ // / destination tuple should be default-initialized with an expression
3143
+ // / provided by the caller.
3144
+ // / FIXME: Yet another indication that ArgumentShuffleExpr uses the wrong
3145
+ // / formulation.
3146
+ CallerDefaultInitialize = -3
3147
+ };
3148
+
3149
+ enum TypeImpact {
3150
+ // / The source value is a tuple which is destructured and modified to
3151
+ // / create the result, which is a tuple.
3152
+ // /
3153
+ // / Example: (x: Int) => (x: Int, y: Int = 0).
3154
+ TupleToTuple,
3155
+
3156
+ // / The source value is a tuple which is destructured and modified to
3157
+ // / create the result, which is a scalar because it has one element and
3158
+ // / no labels.
3159
+ // /
3160
+ // / Example: () -> (_: Int = 0)
3161
+ // / Another example: (Int, Int) => (_: Int...)
3162
+ TupleToScalar,
3163
+
3164
+ // / The source value is an individual value (possibly one with tuple
3165
+ // / type) which is inserted into a particular position in the result,
3166
+ // / which is a tuple.
3167
+ // /
3168
+ // / Example: (Int) -> (_: Int, y: Int = 0)
3169
+ ScalarToTuple
3170
+
3171
+ // (ArgumentShuffleExpr are never created for a scalar-to-scalar conversion.)
3172
+ };
3173
+
3174
+ private:
3175
+ // / If we're doing a varargs shuffle, this is the array type to build.
3176
+ Type VarargsArrayTy;
3177
+
3178
+ // / If there are any default arguments, the owning function
3179
+ // / declaration.
3180
+ ConcreteDeclRef DefaultArgsOwner;
3181
+
3182
+ ArgumentShuffleExpr (Expr *subExpr, ArrayRef<int > elementMapping,
3183
+ TypeImpact typeImpact,
3184
+ ConcreteDeclRef defaultArgsOwner,
3185
+ ArrayRef<unsigned > VariadicArgs,
3186
+ Type VarargsArrayTy,
3187
+ ArrayRef<Expr *> CallerDefaultArgs,
3188
+ Type ty)
3189
+ : ImplicitConversionExpr(ExprKind::ArgumentShuffle, subExpr, ty),
3190
+ VarargsArrayTy (VarargsArrayTy), DefaultArgsOwner(defaultArgsOwner) {
3191
+ Bits.ArgumentShuffleExpr .TypeImpact = typeImpact;
3192
+ Bits.ArgumentShuffleExpr .NumCallerDefaultArgs = CallerDefaultArgs.size ();
3193
+ Bits.ArgumentShuffleExpr .NumElementMappings = elementMapping.size ();
3194
+ Bits.ArgumentShuffleExpr .NumVariadicArgs = VariadicArgs.size ();
3195
+ std::uninitialized_copy (CallerDefaultArgs.begin (), CallerDefaultArgs.end (),
3196
+ getTrailingObjects<Expr*>());
3197
+ std::uninitialized_copy (elementMapping.begin (), elementMapping.end (),
3198
+ getTrailingObjects<int >());
3199
+ std::uninitialized_copy (VariadicArgs.begin (), VariadicArgs.end (),
3200
+ getTrailingObjects<unsigned >());
3201
+ }
3202
+
3203
+ public:
3204
+ static ArgumentShuffleExpr *create (ASTContext &ctx, Expr *subExpr,
3205
+ ArrayRef<int > elementMapping,
3206
+ TypeImpact typeImpact,
3207
+ ConcreteDeclRef defaultArgsOwner,
3208
+ ArrayRef<unsigned > VariadicArgs,
3209
+ Type VarargsArrayTy,
3210
+ ArrayRef<Expr *> CallerDefaultArgs,
3211
+ Type ty);
3212
+
3213
+ ArrayRef<int > getElementMapping () const {
3214
+ return {getTrailingObjects<int >(),
3215
+ static_cast <size_t >(Bits.ArgumentShuffleExpr .NumElementMappings )};
3216
+ }
3217
+
3218
+ // / What is the type impact of this shuffle?
3219
+ TypeImpact getTypeImpact () const {
3220
+ return TypeImpact (Bits.ArgumentShuffleExpr .TypeImpact );
3221
+ }
3222
+
3223
+ bool isSourceScalar () const {
3224
+ return getTypeImpact () == ScalarToTuple;
3225
+ }
3226
+
3227
+ bool isResultScalar () const {
3228
+ return getTypeImpact () == TupleToScalar;
3229
+ }
3230
+
3231
+ Type getVarargsArrayType () const {
3232
+ assert (!VarargsArrayTy.isNull ());
3233
+ return VarargsArrayTy;
3234
+ }
3235
+ Type getVarargsArrayTypeOrNull () const {
3236
+ return VarargsArrayTy;
3237
+ }
3238
+
3239
+ // / Retrieve the argument indices for the variadic arguments.
3240
+ ArrayRef<unsigned > getVariadicArgs () const {
3241
+ return {getTrailingObjects<unsigned >(),
3242
+ static_cast <size_t >(Bits.ArgumentShuffleExpr .NumVariadicArgs )};
3243
+ }
3244
+
3245
+ // / Retrieve the owner of the default arguments.
3246
+ ConcreteDeclRef getDefaultArgsOwner () const { return DefaultArgsOwner; }
3247
+
3248
+ // / Retrieve the caller-defaulted arguments.
3249
+ ArrayRef<Expr *> getCallerDefaultArgs () const {
3250
+ return {getTrailingObjects<Expr*>(),
3251
+ static_cast <size_t >(Bits.ArgumentShuffleExpr .NumCallerDefaultArgs )};
3252
+ }
3253
+
3254
+ // / Retrieve the caller-defaulted arguments.
3255
+ MutableArrayRef<Expr *> getCallerDefaultArgs () {
3256
+ return {getTrailingObjects<Expr*>(),
3257
+ static_cast <size_t >(Bits.ArgumentShuffleExpr .NumCallerDefaultArgs )};
3258
+ }
3259
+
3260
+ static bool classof (const Expr *E) {
3261
+ return E->getKind () == ExprKind::ArgumentShuffle;
3262
+ }
3263
+ };
3264
+
3101
3265
// / LoadExpr - Turn an l-value into an r-value by performing a "load"
3102
3266
// / operation. This operation may actually be a logical operation,
3103
3267
// / i.e. one implemented using a call to a potentially user-defined
@@ -3975,7 +4139,7 @@ class ApplyExpr : public Expr {
3975
4139
3976
4140
// / Returns true if \c e could be used as the call's argument. For most \c ApplyExpr
3977
4141
// / subclasses, this means it is a \c ParenExpr, \c TupleExpr, or
3978
- // / \c TupleShuffleExpr .
4142
+ // / \c ArgumentShuffleExpr .
3979
4143
bool validateArg (Expr *e) const ;
3980
4144
3981
4145
protected:
@@ -5355,7 +5519,7 @@ inline bool ApplyExpr::validateArg(Expr *e) const {
5355
5519
else if (isa<BinaryExpr>(this ))
5356
5520
return isa<TupleExpr>(e);
5357
5521
else
5358
- return isa<ParenExpr>(e) || isa<TupleExpr>(e) || isa<TupleShuffleExpr >(e);
5522
+ return isa<ParenExpr>(e) || isa<TupleExpr>(e) || isa<ArgumentShuffleExpr >(e);
5359
5523
}
5360
5524
5361
5525
inline Expr *const *CollectionExpr::getTrailingObjectsPointer () const {
0 commit comments