Skip to content

Commit d7f4238

Browse files
authored
Merge pull request #10264 from CodaFi/incohate-argumentarianism
[NFC] Decompose function input types
2 parents 6a69dfd + 0b5f442 commit d7f4238

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
@@ -3130,6 +3130,17 @@ getGenericFunctionRecursiveProperties(Type Input, Type Result) {
31303130
return properties;
31313131
}
31323132

3133+
ArrayRef<AnyFunctionType::Param> AnyFunctionType::getParams() const {
3134+
switch (getKind()) {
3135+
case TypeKind::Function:
3136+
return cast<FunctionType>(this)->getParams();
3137+
case TypeKind::GenericFunction:
3138+
return cast<GenericFunctionType>(this)->getParams();
3139+
default:
3140+
llvm_unreachable("Undefined function type");
3141+
}
3142+
}
3143+
31333144
AnyFunctionType *AnyFunctionType::withExtInfo(ExtInfo info) const {
31343145
if (isa<FunctionType>(this))
31353146
return FunctionType::get(getInput(), getResult(), info);
@@ -3144,6 +3155,30 @@ AnyFunctionType *AnyFunctionType::withExtInfo(ExtInfo info) const {
31443155
llvm_unreachable("unhandled function type");
31453156
}
31463157

3158+
static SmallVector<AnyFunctionType::Param, 4> decomposeInputType(Type type) {
3159+
SmallVector<AnyFunctionType::Param, 4> result;
3160+
switch (type->getKind()) {
3161+
case TypeKind::Tuple: {
3162+
auto tupleTy = cast<TupleType>(type.getPointer());
3163+
for (auto &elt : tupleTy->getElements()) {
3164+
AnyFunctionType::Param param(elt);
3165+
result.push_back(param);
3166+
}
3167+
return result;
3168+
}
3169+
3170+
case TypeKind::Paren: {
3171+
auto ty = cast<ParenType>(type.getPointer())->getUnderlyingType();
3172+
result.push_back(AnyFunctionType::Param(ty));
3173+
return result;
3174+
}
3175+
3176+
default:
3177+
result.push_back(AnyFunctionType::Param(type));
3178+
return result;
3179+
}
3180+
}
3181+
31473182
FunctionType *FunctionType::get(Type Input, Type Result,
31483183
const ExtInfo &Info) {
31493184
auto properties = getFunctionRecursiveProperties(Input, Result);
@@ -3155,21 +3190,28 @@ FunctionType *FunctionType::get(Type Input, Type Result,
31553190
FunctionType *&Entry
31563191
= C.Impl.getArena(arena).FunctionTypes[{Input, {Result, attrKey} }];
31573192
if (Entry) return Entry;
3158-
3159-
return Entry = new (C, arena) FunctionType(Input, Result,
3160-
properties,
3161-
Info);
3193+
3194+
auto params = decomposeInputType(Input);
3195+
void *mem = C.Allocate(sizeof(FunctionType) +
3196+
sizeof(AnyFunctionType::Param) * params.size(),
3197+
alignof(FunctionType));
3198+
return Entry = new (mem) FunctionType(params, Input, Result,
3199+
properties, Info);
31623200
}
31633201

31643202
// If the input and result types are canonical, then so is the result.
3165-
FunctionType::FunctionType(Type input, Type output,
3203+
FunctionType::FunctionType(ArrayRef<AnyFunctionType::Param> params,
3204+
Type input, Type output,
31663205
RecursiveTypeProperties properties,
31673206
const ExtInfo &Info)
31683207
: AnyFunctionType(TypeKind::Function,
31693208
(input->isCanonical() && output->isCanonical())
31703209
? &input->getASTContext()
31713210
: nullptr,
3172-
input, output, properties, Info) {}
3211+
input, output, properties, params.size(), Info) {
3212+
std::uninitialized_copy(params.begin(), params.end(),
3213+
getTrailingObjects<AnyFunctionType::Param>());
3214+
}
31733215

31743216
void GenericFunctionType::Profile(llvm::FoldingSetNodeID &ID,
31753217
GenericSignature *sig,
@@ -3215,13 +3257,14 @@ GenericFunctionType::get(GenericSignature *sig,
32153257
= ctx.Impl.GenericFunctionTypes.FindNodeOrInsertPos(id, insertPos)) {
32163258
return result;
32173259
}
3218-
3219-
// Allocate storage for the object.
3220-
void *mem = ctx.Allocate(sizeof(GenericFunctionType),
3260+
3261+
auto params = decomposeInputType(input);
3262+
void *mem = ctx.Allocate(sizeof(GenericFunctionType) +
3263+
sizeof(AnyFunctionType::Param) * params.size(),
32213264
alignof(GenericFunctionType));
32223265

32233266
auto properties = getGenericFunctionRecursiveProperties(input, output);
3224-
auto result = new (mem) GenericFunctionType(sig, input, output, info,
3267+
auto result = new (mem) GenericFunctionType(sig, params, input, output, info,
32253268
isCanonical ? &ctx : nullptr,
32263269
properties);
32273270

@@ -3231,15 +3274,17 @@ GenericFunctionType::get(GenericSignature *sig,
32313274

32323275
GenericFunctionType::GenericFunctionType(
32333276
GenericSignature *sig,
3277+
ArrayRef<AnyFunctionType::Param> params,
32343278
Type input,
32353279
Type result,
32363280
const ExtInfo &info,
32373281
const ASTContext *ctx,
32383282
RecursiveTypeProperties properties)
32393283
: AnyFunctionType(TypeKind::GenericFunction, ctx, input, result,
3240-
properties, info),
3241-
Signature(sig)
3242-
{}
3284+
properties, params.size(), info), Signature(sig) {
3285+
std::uninitialized_copy(params.begin(), params.end(),
3286+
getTrailingObjects<AnyFunctionType::Param>());
3287+
}
32433288

32443289
GenericTypeParamType *GenericTypeParamType::get(unsigned depth, unsigned index,
32453290
const ASTContext &ctx) {

0 commit comments

Comments
 (0)