Skip to content

Commit 0b5f442

Browse files
committed
Decompose function input types
Prepares the AST for future work to eliminate `getInput()` and perform function type argument matching in a less ad-hoc manner.
1 parent db3796d commit 0b5f442

File tree

2 files changed

+126
-26
lines changed

2 files changed

+126
-26
lines changed

include/swift/AST/Types.h

Lines changed: 68 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2297,10 +2297,44 @@ getSILFunctionLanguage(SILFunctionTypeRepresentation rep) {
22972297
class AnyFunctionType : public TypeBase {
22982298
const Type Input;
22992299
const Type Output;
2300-
2300+
const unsigned NumParams;
2301+
23012302
public:
23022303
using Representation = FunctionTypeRepresentation;
23032304

2305+
class Param {
2306+
public:
2307+
explicit Param(Type t) : Ty(t), Label(Identifier()), Flags() {}
2308+
explicit Param(const TupleTypeElt &tte)
2309+
: Ty(tte.getType()), Label(tte.getName()),
2310+
Flags(tte.getParameterFlags()) {}
2311+
2312+
private:
2313+
/// The type of the parameter. For a variadic parameter, this is the
2314+
/// element type.
2315+
Type Ty;
2316+
2317+
// The label associated with the parameter, if any.
2318+
Identifier Label;
2319+
2320+
/// Parameter specific flags.
2321+
ParameterTypeFlags Flags = {};
2322+
2323+
public:
2324+
Type getType() const { return Ty; }
2325+
2326+
Identifier getLabel() const { return Label; }
2327+
2328+
/// Whether the parameter is varargs
2329+
bool isVariadic() const { return Flags.isVariadic(); }
2330+
2331+
/// Whether the parameter is marked '@autoclosure'
2332+
bool isAutoClosure() const { return Flags.isAutoClosure(); }
2333+
2334+
/// Whether the parameter is marked '@escaping'
2335+
bool isEscaping() const { return Flags.isEscaping(); }
2336+
};
2337+
23042338
/// \brief A class which abstracts out some details necessary for
23052339
/// making a call.
23062340
class ExtInfo {
@@ -2442,16 +2476,18 @@ class AnyFunctionType : public TypeBase {
24422476
protected:
24432477
AnyFunctionType(TypeKind Kind, const ASTContext *CanTypeContext,
24442478
Type Input, Type Output, RecursiveTypeProperties properties,
2445-
const ExtInfo &Info)
2446-
: TypeBase(Kind, CanTypeContext, properties), Input(Input), Output(Output) {
2479+
unsigned NumParams, const ExtInfo &Info)
2480+
: TypeBase(Kind, CanTypeContext, properties), Input(Input), Output(Output),
2481+
NumParams(NumParams) {
24472482
AnyFunctionTypeBits.ExtInfo = Info.Bits;
24482483
}
24492484

24502485
public:
2451-
24522486
Type getInput() const { return Input; }
24532487
Type getResult() const { return Output; }
2454-
2488+
ArrayRef<AnyFunctionType::Param> getParams() const;
2489+
unsigned getNumParams() const { return NumParams; }
2490+
24552491
ExtInfo getExtInfo() const {
24562492
return ExtInfo(AnyFunctionTypeBits.ExtInfo);
24572493
}
@@ -2501,22 +2537,32 @@ END_CAN_TYPE_WRAPPER(AnyFunctionType, Type)
25012537
///
25022538
/// For example:
25032539
/// let x : (Float, Int) -> Int
2504-
class FunctionType : public AnyFunctionType {
2540+
class FunctionType final : public AnyFunctionType,
2541+
private llvm::TrailingObjects<FunctionType, AnyFunctionType::Param> {
2542+
friend TrailingObjects;
2543+
25052544
public:
25062545
/// 'Constructor' Factory Function
25072546
static FunctionType *get(Type Input, Type Result) {
25082547
return get(Input, Result, ExtInfo());
25092548
}
25102549

25112550
static FunctionType *get(Type Input, Type Result, const ExtInfo &Info);
2512-
2551+
2552+
2553+
// Retrieve the input parameters of this function type.
2554+
ArrayRef<AnyFunctionType::Param> getParams() const {
2555+
return {getTrailingObjects<AnyFunctionType::Param>(), getNumParams()};
2556+
}
2557+
25132558
// Implement isa/cast/dyncast/etc.
25142559
static bool classof(const TypeBase *T) {
25152560
return T->getKind() == TypeKind::Function;
25162561
}
2517-
2562+
25182563
private:
2519-
FunctionType(Type Input, Type Result,
2564+
FunctionType(ArrayRef<AnyFunctionType::Param> params,
2565+
Type Input, Type Result,
25202566
RecursiveTypeProperties properties,
25212567
const ExtInfo &Info);
25222568
};
@@ -2587,25 +2633,34 @@ std::string getParamListAsString(ArrayRef<CallArgParam> parameters);
25872633
/// on those parameters and dependent member types thereof. The input and
25882634
/// output types of the generic function can be expressed in terms of those
25892635
/// generic parameters.
2590-
class GenericFunctionType : public AnyFunctionType,
2591-
public llvm::FoldingSetNode
2592-
{
2636+
class GenericFunctionType final : public AnyFunctionType,
2637+
public llvm::FoldingSetNode,
2638+
private llvm::TrailingObjects<GenericFunctionType, AnyFunctionType::Param> {
2639+
friend TrailingObjects;
2640+
25932641
GenericSignature *Signature;
25942642

25952643
/// Construct a new generic function type.
25962644
GenericFunctionType(GenericSignature *sig,
2645+
ArrayRef<AnyFunctionType::Param> params,
25972646
Type input,
25982647
Type result,
25992648
const ExtInfo &info,
26002649
const ASTContext *ctx,
26012650
RecursiveTypeProperties properties);
2651+
26022652
public:
26032653
/// Create a new generic function type.
26042654
static GenericFunctionType *get(GenericSignature *sig,
26052655
Type input,
26062656
Type result,
26072657
const ExtInfo &info);
2608-
2658+
2659+
// Retrieve the input parameters of this function type.
2660+
ArrayRef<AnyFunctionType::Param> getParams() const {
2661+
return {getTrailingObjects<AnyFunctionType::Param>(), getNumParams()};
2662+
}
2663+
26092664
/// Retrieve the generic signature of this function type.
26102665
GenericSignature *getGenericSignature() const {
26112666
return Signature;

lib/AST/ASTContext.cpp

Lines changed: 58 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -3136,6 +3136,17 @@ getGenericFunctionRecursiveProperties(Type Input, Type Result) {
31363136
return properties;
31373137
}
31383138

3139+
ArrayRef<AnyFunctionType::Param> AnyFunctionType::getParams() const {
3140+
switch (getKind()) {
3141+
case TypeKind::Function:
3142+
return cast<FunctionType>(this)->getParams();
3143+
case TypeKind::GenericFunction:
3144+
return cast<GenericFunctionType>(this)->getParams();
3145+
default:
3146+
llvm_unreachable("Undefined function type");
3147+
}
3148+
}
3149+
31393150
AnyFunctionType *AnyFunctionType::withExtInfo(ExtInfo info) const {
31403151
if (isa<FunctionType>(this))
31413152
return FunctionType::get(getInput(), getResult(), info);
@@ -3150,6 +3161,30 @@ AnyFunctionType *AnyFunctionType::withExtInfo(ExtInfo info) const {
31503161
llvm_unreachable("unhandled function type");
31513162
}
31523163

3164+
static SmallVector<AnyFunctionType::Param, 4> decomposeInputType(Type type) {
3165+
SmallVector<AnyFunctionType::Param, 4> result;
3166+
switch (type->getKind()) {
3167+
case TypeKind::Tuple: {
3168+
auto tupleTy = cast<TupleType>(type.getPointer());
3169+
for (auto &elt : tupleTy->getElements()) {
3170+
AnyFunctionType::Param param(elt);
3171+
result.push_back(param);
3172+
}
3173+
return result;
3174+
}
3175+
3176+
case TypeKind::Paren: {
3177+
auto ty = cast<ParenType>(type.getPointer())->getUnderlyingType();
3178+
result.push_back(AnyFunctionType::Param(ty));
3179+
return result;
3180+
}
3181+
3182+
default:
3183+
result.push_back(AnyFunctionType::Param(type));
3184+
return result;
3185+
}
3186+
}
3187+
31533188
FunctionType *FunctionType::get(Type Input, Type Result,
31543189
const ExtInfo &Info) {
31553190
auto properties = getFunctionRecursiveProperties(Input, Result);
@@ -3161,21 +3196,28 @@ FunctionType *FunctionType::get(Type Input, Type Result,
31613196
FunctionType *&Entry
31623197
= C.Impl.getArena(arena).FunctionTypes[{Input, {Result, attrKey} }];
31633198
if (Entry) return Entry;
3164-
3165-
return Entry = new (C, arena) FunctionType(Input, Result,
3166-
properties,
3167-
Info);
3199+
3200+
auto params = decomposeInputType(Input);
3201+
void *mem = C.Allocate(sizeof(FunctionType) +
3202+
sizeof(AnyFunctionType::Param) * params.size(),
3203+
alignof(FunctionType));
3204+
return Entry = new (mem) FunctionType(params, Input, Result,
3205+
properties, Info);
31683206
}
31693207

31703208
// If the input and result types are canonical, then so is the result.
3171-
FunctionType::FunctionType(Type input, Type output,
3209+
FunctionType::FunctionType(ArrayRef<AnyFunctionType::Param> params,
3210+
Type input, Type output,
31723211
RecursiveTypeProperties properties,
31733212
const ExtInfo &Info)
31743213
: AnyFunctionType(TypeKind::Function,
31753214
(input->isCanonical() && output->isCanonical())
31763215
? &input->getASTContext()
31773216
: nullptr,
3178-
input, output, properties, Info) {}
3217+
input, output, properties, params.size(), Info) {
3218+
std::uninitialized_copy(params.begin(), params.end(),
3219+
getTrailingObjects<AnyFunctionType::Param>());
3220+
}
31793221

31803222
void GenericFunctionType::Profile(llvm::FoldingSetNodeID &ID,
31813223
GenericSignature *sig,
@@ -3221,13 +3263,14 @@ GenericFunctionType::get(GenericSignature *sig,
32213263
= ctx.Impl.GenericFunctionTypes.FindNodeOrInsertPos(id, insertPos)) {
32223264
return result;
32233265
}
3224-
3225-
// Allocate storage for the object.
3226-
void *mem = ctx.Allocate(sizeof(GenericFunctionType),
3266+
3267+
auto params = decomposeInputType(input);
3268+
void *mem = ctx.Allocate(sizeof(GenericFunctionType) +
3269+
sizeof(AnyFunctionType::Param) * params.size(),
32273270
alignof(GenericFunctionType));
32283271

32293272
auto properties = getGenericFunctionRecursiveProperties(input, output);
3230-
auto result = new (mem) GenericFunctionType(sig, input, output, info,
3273+
auto result = new (mem) GenericFunctionType(sig, params, input, output, info,
32313274
isCanonical ? &ctx : nullptr,
32323275
properties);
32333276

@@ -3237,15 +3280,17 @@ GenericFunctionType::get(GenericSignature *sig,
32373280

32383281
GenericFunctionType::GenericFunctionType(
32393282
GenericSignature *sig,
3283+
ArrayRef<AnyFunctionType::Param> params,
32403284
Type input,
32413285
Type result,
32423286
const ExtInfo &info,
32433287
const ASTContext *ctx,
32443288
RecursiveTypeProperties properties)
32453289
: AnyFunctionType(TypeKind::GenericFunction, ctx, input, result,
3246-
properties, info),
3247-
Signature(sig)
3248-
{}
3290+
properties, params.size(), info), Signature(sig) {
3291+
std::uninitialized_copy(params.begin(), params.end(),
3292+
getTrailingObjects<AnyFunctionType::Param>());
3293+
}
32493294

32503295
GenericTypeParamType *GenericTypeParamType::get(unsigned depth, unsigned index,
32513296
const ASTContext &ctx) {

0 commit comments

Comments
 (0)