Skip to content

New way of directly building FunctionType::Params from ParameterLists #18651

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

Merged
merged 8 commits into from
Aug 11, 2018
8 changes: 2 additions & 6 deletions include/swift/AST/Decl.h
Original file line number Diff line number Diff line change
Expand Up @@ -4729,10 +4729,6 @@ class ParamDecl : public VarDecl {
/// was specified separately from the parameter name.
SourceLoc getArgumentNameLoc() const { return ArgumentNameLoc; }

/// Retrieve the parameter type flags corresponding to the declaration of
/// this parameter's argument type.
ParameterTypeFlags getParameterFlags() const;

SourceLoc getSpecifierLoc() const { return SpecifierLoc; }

bool isTypeLocImplicit() const { return Bits.ParamDecl.IsTypeLocImplicit; }
Expand Down Expand Up @@ -5772,8 +5768,8 @@ class EnumElementDecl : public ValueDecl {
}

/// Set the interface type of this enum element to the constructor function
/// type; (Self) -> Result or (Self) -> (Args...) -> Result.
bool computeType();
/// type; (Self.Type) -> Self or (Self.Type) -> (Args...) -> Self.
void computeType();

Type getArgumentInterfaceType() const;

Expand Down
23 changes: 7 additions & 16 deletions include/swift/AST/ParameterList.h
Original file line number Diff line number Diff line change
Expand Up @@ -123,23 +123,14 @@ class alignas(ParamDecl *) ParameterList final :
ParameterList *clone(const ASTContext &C,
OptionSet<CloneFlags> options = None) const;

/// Return a TupleType or ParenType for this parameter list,
/// based on types provided by a callback.
Type getType(const ASTContext &C,
llvm::function_ref<Type(ParamDecl *)> getType) const;

/// Return a TupleType or ParenType for this parameter list, written in terms
/// of contextual archetypes.
Type getType(const ASTContext &C) const;
/// Return a list of function parameters for this parameter list,
/// based on the interface types of the parameters in this list.
void getParams(SmallVectorImpl<AnyFunctionType::Param> &params) const;

/// Return a TupleType or ParenType for this parameter list, written in terms
/// of interface types.
Type getInterfaceType(const ASTContext &C) const;

/// Return the full function type for a set of curried parameter lists that
/// returns the specified result type written in terms of interface types.
static Type getFullInterfaceType(Type resultType, ArrayRef<ParameterList*> PL,
const ASTContext &C);
/// Return a list of function parameters for this parameter list,
/// based on types provided by a callback.
void getParams(SmallVectorImpl<AnyFunctionType::Param> &params,
llvm::function_ref<Type(ParamDecl *)> getType) const;


/// Return the full source range of this parameter.
Expand Down
51 changes: 27 additions & 24 deletions lib/AST/Decl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4799,11 +4799,6 @@ ParamDecl *ParamDecl::createSelf(SourceLoc loc, DeclContext *DC,
return selfDecl;
}

ParameterTypeFlags ParamDecl::getParameterFlags() const {
return ParameterTypeFlags::fromParameterType(getType(), isVariadic(),
getValueOwnership());
}

/// Return the full source range of this parameter.
SourceRange ParamDecl::getSourceRange() const {
SourceLoc APINameLoc = getArgumentNameLoc();
Expand Down Expand Up @@ -4969,17 +4964,18 @@ Type SubscriptDecl::getElementInterfaceType() const {
}

void SubscriptDecl::computeType() {
auto &ctx = getASTContext();

auto elementTy = getElementTypeLoc().getType();
auto indicesTy = getIndices()->getInterfaceType(ctx);
Type funcTy;

SmallVector<AnyFunctionType::Param, 2> argTy;
getIndices()->getParams(argTy);

Type funcTy;
if (auto *sig = getGenericSignature())
funcTy = GenericFunctionType::get(sig, indicesTy, elementTy,
funcTy = GenericFunctionType::get(sig, argTy, elementTy,
AnyFunctionType::ExtInfo());
else
funcTy = FunctionType::get(indicesTy, elementTy);
funcTy = FunctionType::get(argTy, elementTy,
AnyFunctionType::ExtInfo());

// Record the interface type.
setInterfaceType(funcTy);
Expand Down Expand Up @@ -5403,8 +5399,7 @@ void AbstractFunctionDecl::computeType(AnyFunctionType::ExtInfo info) {

{
SmallVector<AnyFunctionType::Param, 4> argTy;
AnyFunctionType::decomposeInput(
getParameters()->getInterfaceType(ctx), argTy);
getParameters()->getParams(argTy);

// 'throws' only applies to the innermost function.
info = info.withThrows(hasThrows());
Expand Down Expand Up @@ -5724,30 +5719,38 @@ SourceRange EnumElementDecl::getSourceRange() const {
return {getStartLoc(), getNameLoc()};
}

bool EnumElementDecl::computeType() {
void EnumElementDecl::computeType() {
assert(!hasInterfaceType());

EnumDecl *ED = getParentEnum();
Type resultTy = ED->getDeclaredInterfaceType();
auto &ctx = getASTContext();
auto *ED = getParentEnum();

// The type of the enum element is either (Self.Type) -> Self
// or (Self.Type) -> (Args...) -> Self.
auto resultTy = ED->getDeclaredInterfaceType();

Type selfTy = MetatypeType::get(resultTy);
SmallVector<AnyFunctionType::Param, 1> selfTy;
selfTy.emplace_back(MetatypeType::get(resultTy, ctx),
Identifier(),
ParameterTypeFlags());

// The type of the enum element is either (T) -> T or (T) -> ArgType -> T.
if (auto *PL = getParameterList()) {
auto paramTy = PL->getInterfaceType(getASTContext());
resultTy = FunctionType::get(paramTy, resultTy);
SmallVector<AnyFunctionType::Param, 4> argTy;
PL->getParams(argTy);

resultTy = FunctionType::get(argTy, resultTy,
AnyFunctionType::ExtInfo());
}

if (auto *genericSig = ED->getGenericSignatureOfContext())
if (auto *genericSig = ED->getGenericSignature())
resultTy = GenericFunctionType::get(genericSig, selfTy, resultTy,
AnyFunctionType::ExtInfo());
else
resultTy = FunctionType::get(selfTy, resultTy);
resultTy = FunctionType::get(selfTy, resultTy,
AnyFunctionType::ExtInfo());

// Record the interface type.
setInterfaceType(resultTy);

return true;
}

Type EnumElementDecl::getArgumentInterfaceType() const {
Expand Down
59 changes: 16 additions & 43 deletions lib/AST/Parameter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -87,56 +87,29 @@ ParameterList *ParameterList::clone(const ASTContext &C,
return create(C, params);
}

/// Return a TupleType or ParenType for this parameter list,
/// based on types provided by a callback.
Type ParameterList::getType(
const ASTContext &C, llvm::function_ref<Type(ParamDecl *)> getType) const {
if (size() == 0)
return TupleType::getEmpty(C);
void ParameterList::getParams(
SmallVectorImpl<AnyFunctionType::Param> &params) const {
getParams(params,
[](ParamDecl *decl) { return decl->getInterfaceType(); });
}

SmallVector<TupleTypeElt, 8> argumentInfo;
void ParameterList::getParams(
SmallVectorImpl<AnyFunctionType::Param> &params,
llvm::function_ref<Type(ParamDecl *)> getType) const {
if (size() == 0)
return;

for (auto P : *this) {
auto type = getType(P);
argumentInfo.emplace_back(
type->getInOutObjectType(), P->getArgumentName(),
ParameterTypeFlags::fromParameterType(type, P->isVariadic(),
P->getValueOwnership()));
}

return TupleType::get(argumentInfo, C);
}

/// Return a TupleType or ParenType for this parameter list, written in terms
/// of contextual archetypes.
Type ParameterList::getType(const ASTContext &C) const {
return getType(C, [](ParamDecl *P) { return P->getType(); });
}

/// Return a TupleType or ParenType for this parameter list, written in terms
/// of interface types.
Type ParameterList::getInterfaceType(const ASTContext &C) const {
return getType(C, [](ParamDecl *P) {
auto type = P->getInterfaceType();
assert(!type->hasArchetype());
return type;
});
}

if (P->isVariadic())
type = ParamDecl::getVarargBaseTy(type);

/// Return the full function type for a set of curried parameter lists that
/// returns the specified result type. This returns a null type if one of the
/// ParamDecls does not have a type set for it yet.
///
Type ParameterList::getFullInterfaceType(Type resultType,
ArrayRef<ParameterList*> PLL,
const ASTContext &C) {
auto result = resultType;
for (auto PL : reversed(PLL)) {
auto paramType = PL->getInterfaceType(C);
result = FunctionType::get(paramType, result);
auto label = P->getArgumentName();
auto flags = ParameterTypeFlags::fromParameterType(type, P->isVariadic(),
P->getValueOwnership());
params.emplace_back(type, label, flags);
}
return result;
}


Expand Down
23 changes: 9 additions & 14 deletions lib/ClangImporter/ImportDecl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3499,9 +3499,7 @@ namespace {
if (!importedType)
return nullptr;

Type type = importedType.getType();

auto resultTy = type->castTo<FunctionType>()->getResult();
auto resultTy = importedType.getType();
auto loc = Impl.importSourceLoc(decl->getLocation());

if (name && name.isSimpleName()) {
Expand All @@ -3519,7 +3517,7 @@ namespace {
resultTy, /*throws*/ false,
dc, decl);

result->setInterfaceType(type);
result->computeType();
result->setValidationToChecked();
result->setIsObjC(false);
result->setIsDynamic(false);
Expand Down Expand Up @@ -4041,9 +4039,7 @@ namespace {

result->setAccess(getOverridableAccessLevel(dc));

auto resultTy = importedType.getType()
->castTo<FunctionType>()->getResult();

auto resultTy = importedType.getType();
auto isIUO = importedType.isImplicitlyUnwrapped();

// If the method has a related result type that is representable
Expand Down Expand Up @@ -6100,8 +6096,7 @@ ConstructorDecl *SwiftDeclConverter::importConstructor(
return nullptr;

// Determine the failability of this initializer.
auto oldFnType = importedType.getType()->castTo<AnyFunctionType>();
bool resultIsOptional = (bool) oldFnType->getResult()->getOptionalObjectType();
bool resultIsOptional = (bool) importedType.getType()->getOptionalObjectType();

// Update the failability appropriately based on the imported method type.
assert(resultIsOptional || !importedType.isImplicitlyUnwrapped());
Expand All @@ -6119,7 +6114,9 @@ ConstructorDecl *SwiftDeclConverter::importConstructor(

// Look for other imported constructors that occur in this context with
// the same name.
auto allocParams = oldFnType->getParams();
SmallVector<AnyFunctionType::Param, 4> allocParams;
bodyParams->getParams(allocParams);

bool ignoreNewExtensions = isa<ClassDecl>(dc);
for (auto other : ownerNominal->lookupDirect(importedName.getDeclName(),
ignoreNewExtensions)) {
Expand Down Expand Up @@ -6359,14 +6356,12 @@ void SwiftDeclConverter::recordObjCOverride(SubscriptDecl *subscript) {

// Compute the type of indices for our own subscript operation, lazily.
if (!unlabeledIndices) {
unlabeledIndices = subscript->getIndices()
->getInterfaceType(Impl.SwiftContext)
unlabeledIndices = subscript->getIndicesInterfaceType()
->getUnlabeledType(Impl.SwiftContext);
}

// Compute the type of indices for the subscript we found.
auto parentUnlabeledIndices = parentSub->getIndices()
->getInterfaceType(Impl.SwiftContext)
auto parentUnlabeledIndices = parentSub->getIndicesInterfaceType()
->getUnlabeledType(Impl.SwiftContext);
if (!unlabeledIndices->isEqual(parentUnlabeledIndices))
continue;
Expand Down
Loading