-
Notifications
You must be signed in to change notification settings - Fork 10.5k
[NFC] Refactor parameter counting #10271
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2282,7 +2282,35 @@ getSILFunctionLanguage(SILFunctionTypeRepresentation rep) { | |
|
||
llvm_unreachable("Unhandled SILFunctionTypeRepresentation in switch."); | ||
} | ||
|
||
|
||
/// A call argument or parameter. | ||
struct CallArgParam { | ||
/// The type of the argument or parameter. For a variadic parameter, | ||
/// this is the element type. | ||
Type Ty; | ||
|
||
// The label associated with the argument or parameter, if any. | ||
Identifier Label; | ||
|
||
/// Whether the parameter has a default argument. Not valid for arguments. | ||
bool HasDefaultArgument = false; | ||
|
||
/// Parameter specific flags, not valid for arguments | ||
ParameterTypeFlags parameterFlags = {}; | ||
|
||
/// Whether the argument or parameter has a label. | ||
bool hasLabel() const { return !Label.empty(); } | ||
|
||
/// Whether the parameter is varargs | ||
bool isVariadic() const { return parameterFlags.isVariadic(); } | ||
|
||
/// Whether the parameter is autoclosure | ||
bool isAutoClosure() const { return parameterFlags.isAutoClosure(); } | ||
|
||
/// Whether the parameter is escaping | ||
bool isEscaping() const { return parameterFlags.isEscaping(); } | ||
}; | ||
|
||
/// AnyFunctionType - A function type has a single input and result, but | ||
/// these types may be tuples, for example: | ||
/// "(int) -> int" or "(a : int, b : int) -> (int, int)". | ||
|
@@ -2295,7 +2323,8 @@ getSILFunctionLanguage(SILFunctionTypeRepresentation rep) { | |
/// be 'thin', indicating that a function value has no capture context and can be | ||
/// represented at the binary level as a single function pointer. | ||
class AnyFunctionType : public TypeBase { | ||
const Type Input; | ||
const ArrayRef<CallArgParam> Input; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'd prefer to tail-allocate the parameters in the subclasses, so we don't pay for this extra pointer in such a common type. |
||
const Type RawInput; | ||
const Type Output; | ||
|
||
public: | ||
|
@@ -2441,15 +2470,14 @@ class AnyFunctionType : public TypeBase { | |
|
||
protected: | ||
AnyFunctionType(TypeKind Kind, const ASTContext *CanTypeContext, | ||
Type Input, Type Output, RecursiveTypeProperties properties, | ||
const ExtInfo &Info) | ||
: TypeBase(Kind, CanTypeContext, properties), Input(Input), Output(Output) { | ||
AnyFunctionTypeBits.ExtInfo = Info.Bits; | ||
} | ||
ArrayRef<CallArgParam> Input, Type RawInput, Type Output, | ||
RecursiveTypeProperties properties, | ||
const ExtInfo &Info); | ||
|
||
public: | ||
|
||
Type getInput() const { return Input; } | ||
|
||
const ArrayRef<CallArgParam> getParams() const { return Input; } | ||
Type getInput() const { return RawInput; } | ||
Type getResult() const { return Output; } | ||
|
||
ExtInfo getExtInfo() const { | ||
|
@@ -2533,41 +2561,14 @@ BEGIN_CAN_TYPE_WRAPPER(FunctionType, AnyFunctionType) | |
return CanFunctionType(cast<FunctionType>(getPointer()->withExtInfo(info))); | ||
} | ||
END_CAN_TYPE_WRAPPER(FunctionType, AnyFunctionType) | ||
|
||
/// A call argument or parameter. | ||
struct CallArgParam { | ||
/// The type of the argument or parameter. For a variadic parameter, | ||
/// this is the element type. | ||
Type Ty; | ||
|
||
// The label associated with the argument or parameter, if any. | ||
Identifier Label; | ||
|
||
/// Whether the parameter has a default argument. Not valid for arguments. | ||
bool HasDefaultArgument = false; | ||
|
||
/// Parameter specific flags, not valid for arguments | ||
ParameterTypeFlags parameterFlags = {}; | ||
|
||
/// Whether the argument or parameter has a label. | ||
bool hasLabel() const { return !Label.empty(); } | ||
|
||
/// Whether the parameter is varargs | ||
bool isVariadic() const { return parameterFlags.isVariadic(); } | ||
|
||
/// Whether the parameter is autoclosure | ||
bool isAutoClosure() const { return parameterFlags.isAutoClosure(); } | ||
|
||
/// Whether the parameter is escaping | ||
bool isEscaping() const { return parameterFlags.isEscaping(); } | ||
}; | ||
|
||
|
||
/// Break an argument type into an array of \c CallArgParams. | ||
/// | ||
/// \param type The type to decompose. | ||
/// \param argumentLabels The argument labels to use. | ||
SmallVector<CallArgParam, 4> | ||
decomposeArgType(Type type, ArrayRef<Identifier> argumentLabels); | ||
decomposeArgType(Type type, ArrayRef<Identifier> argumentLabels, | ||
bool inAnyFunctionType = false); | ||
|
||
/// Break a parameter type into an array of \c CallArgParams. | ||
/// | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -3136,6 +3136,16 @@ getGenericFunctionRecursiveProperties(Type Input, Type Result) { | |
return properties; | ||
} | ||
|
||
AnyFunctionType::AnyFunctionType(TypeKind Kind, const ASTContext *CanTypeContext, | ||
ArrayRef<CallArgParam> Input, Type RawInput, Type Output, | ||
RecursiveTypeProperties properties, | ||
const ExtInfo &Info) | ||
: TypeBase(Kind, CanTypeContext, properties), | ||
Input((CanTypeContext ?: &RawInput->getASTContext())->AllocateCopy(Input)), | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Hmm... I'm confused why we're doing the |
||
RawInput(RawInput), Output(Output) { | ||
AnyFunctionTypeBits.ExtInfo = Info.Bits; | ||
} | ||
|
||
AnyFunctionType *AnyFunctionType::withExtInfo(ExtInfo info) const { | ||
if (isa<FunctionType>(this)) | ||
return FunctionType::get(getInput(), getResult(), info); | ||
|
@@ -3167,6 +3177,17 @@ FunctionType *FunctionType::get(Type Input, Type Result, | |
Info); | ||
} | ||
|
||
static SmallVector<CallArgParam, 4> decomposeInput(Type ty) { | ||
if (auto *TTy = dyn_cast<TupleType>(ty.getPointer())) { | ||
SmallVector<Identifier, 4> labels; | ||
for (auto &ttyElt : TTy->getElements()) { | ||
labels.push_back(ttyElt.getName()); | ||
} | ||
return decomposeArgType(TTy, labels, /*inAnyFunctionType*/true); | ||
} | ||
return decomposeArgType(ty, { Identifier() }, /*inAnyFunctionType*/true); | ||
} | ||
|
||
// If the input and result types are canonical, then so is the result. | ||
FunctionType::FunctionType(Type input, Type output, | ||
RecursiveTypeProperties properties, | ||
|
@@ -3175,7 +3196,7 @@ FunctionType::FunctionType(Type input, Type output, | |
(input->isCanonical() && output->isCanonical()) | ||
? &input->getASTContext() | ||
: nullptr, | ||
input, output, properties, Info) {} | ||
decomposeInput(input), input, output, properties, Info) {} | ||
|
||
void GenericFunctionType::Profile(llvm::FoldingSetNodeID &ID, | ||
GenericSignature *sig, | ||
|
@@ -3242,8 +3263,8 @@ GenericFunctionType::GenericFunctionType( | |
const ExtInfo &info, | ||
const ASTContext *ctx, | ||
RecursiveTypeProperties properties) | ||
: AnyFunctionType(TypeKind::GenericFunction, ctx, input, result, | ||
properties, info), | ||
: AnyFunctionType(TypeKind::GenericFunction, ctx, decomposeInput(input), | ||
input, result, properties, info), | ||
Signature(sig) | ||
{} | ||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
HasDefaultArgument
doesn't belong in the type. I think you will need to use something other thanCallArgParam
for your storage.