Skip to content

Commit 6c8a05d

Browse files
committed
[AST] Implement default expression type request and accessors
1 parent 3cab840 commit 6c8a05d

File tree

8 files changed

+92
-5
lines changed

8 files changed

+92
-5
lines changed

include/swift/AST/Decl.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5504,6 +5504,7 @@ enum class ParamSpecifier : uint8_t {
55045504
class ParamDecl : public VarDecl {
55055505
friend class DefaultArgumentInitContextRequest;
55065506
friend class DefaultArgumentExprRequest;
5507+
friend class DefaultArgumentTypeRequest;
55075508

55085509
enum class ArgumentNameFlags : uint8_t {
55095510
/// Whether or not this parameter is destructed.
@@ -5524,6 +5525,9 @@ class ParamDecl : public VarDecl {
55245525
struct alignas(1 << StoredDefaultArgumentAlignInBits) StoredDefaultArgument {
55255526
PointerUnion<Expr *, VarDecl *> DefaultArg;
55265527

5528+
/// The type of the default argument expression.
5529+
Type ExprType;
5530+
55275531
/// Stores the context for the default argument as well as a bit to
55285532
/// indicate whether the default expression has been type-checked.
55295533
llvm::PointerIntPair<Initializer *, 1, bool> InitContextAndIsTypeChecked;
@@ -5641,6 +5645,10 @@ class ParamDecl : public VarDecl {
56415645
return nullptr;
56425646
}
56435647

5648+
/// Retrieve the type of the default expression (if any) associated with
5649+
/// this parameter declaration.
5650+
Type getTypeOfDefaultExpr() const;
5651+
56445652
VarDecl *getStoredProperty() const {
56455653
if (auto stored = DefaultValueAndFlags.getPointer())
56465654
return stored->DefaultArg.dyn_cast<VarDecl *>();
@@ -5655,6 +5663,10 @@ class ParamDecl : public VarDecl {
56555663
/// parameter's fully type-checked default argument.
56565664
void setDefaultExpr(Expr *E, bool isTypeChecked);
56575665

5666+
/// Sets a type of default expression associated with this parameter.
5667+
/// This should only be called by deserialization.
5668+
void setDefaultExprType(Type type);
5669+
56585670
void setStoredProperty(VarDecl *var);
56595671

56605672
/// Retrieve the initializer context for the parameter's default argument.

include/swift/AST/TypeCheckRequests.h

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ class AccessorDecl;
4141
enum class AccessorKind;
4242
class ContextualPattern;
4343
class DefaultArgumentExpr;
44+
class DefaultArgumentType;
4445
class ClosureExpr;
4546
class GenericParamList;
4647
class PrecedenceGroupDecl;
@@ -2665,6 +2666,26 @@ class DefaultArgumentExprRequest
26652666
void cacheResult(Expr *expr) const;
26662667
};
26672668

2669+
/// Computes the type of the default expression for a given parameter.
2670+
class DefaultArgumentTypeRequest
2671+
: public SimpleRequest<DefaultArgumentTypeRequest, Type(ParamDecl *),
2672+
RequestFlags::SeparatelyCached> {
2673+
public:
2674+
using SimpleRequest::SimpleRequest;
2675+
2676+
private:
2677+
friend SimpleRequest;
2678+
2679+
// Evaluation.
2680+
Type evaluate(Evaluator &evaluator, ParamDecl *param) const;
2681+
2682+
public:
2683+
// Separate caching.
2684+
bool isCached() const { return true; }
2685+
Optional<Type> getCachedResult() const;
2686+
void cacheResult(Type type) const;
2687+
};
2688+
26682689
/// Computes the fully type-checked caller-side default argument within the
26692690
/// context of the call site that it will be inserted into.
26702691
class CallerSideDefaultArgExprRequest

include/swift/AST/TypeCheckerTypeIDZone.def

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,8 @@ SWIFT_REQUEST(TypeChecker, CustomAttrTypeRequest,
5959
SeparatelyCached, NoLocationInfo)
6060
SWIFT_REQUEST(TypeChecker, DefaultArgumentExprRequest,
6161
Expr *(ParamDecl *), SeparatelyCached, NoLocationInfo)
62+
SWIFT_REQUEST(TypeChecker, DefaultArgumentTypeRequest,
63+
Type(ParamDecl *), SeparatelyCached, NoLocationInfo)
6264
SWIFT_REQUEST(TypeChecker, DefaultArgumentInitContextRequest,
6365
Initializer *(ParamDecl *), SeparatelyCached, NoLocationInfo)
6466
SWIFT_REQUEST(TypeChecker, DefaultDefinitionTypeRequest,

lib/AST/Decl.cpp

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6992,6 +6992,18 @@ Expr *ParamDecl::getTypeCheckedDefaultExpr() const {
69926992
return new (ctx) ErrorExpr(getSourceRange(), ErrorType::get(ctx));
69936993
}
69946994

6995+
Type ParamDecl::getTypeOfDefaultExpr() const {
6996+
auto &ctx = getASTContext();
6997+
6998+
if (Type type = evaluateOrDefault(
6999+
ctx.evaluator,
7000+
DefaultArgumentTypeRequest{const_cast<ParamDecl *>(this)}, nullptr)) {
7001+
return type;
7002+
}
7003+
7004+
return Type();
7005+
}
7006+
69957007
void ParamDecl::setDefaultExpr(Expr *E, bool isTypeChecked) {
69967008
if (!DefaultValueAndFlags.getPointer()) {
69977009
if (!E) return;
@@ -7009,9 +7021,20 @@ void ParamDecl::setDefaultExpr(Expr *E, bool isTypeChecked) {
70097021
"Can't overwrite type-checked default with un-type-checked default");
70107022
}
70117023
defaultInfo->DefaultArg = E;
7024+
defaultInfo->ExprType = E->getType();
70127025
defaultInfo->InitContextAndIsTypeChecked.setInt(isTypeChecked);
70137026
}
70147027

7028+
void ParamDecl::setDefaultExprType(Type type) {
7029+
if (!DefaultValueAndFlags.getPointer()) {
7030+
DefaultValueAndFlags.setPointer(
7031+
getASTContext().Allocate<StoredDefaultArgument>());
7032+
}
7033+
7034+
auto *defaultInfo = DefaultValueAndFlags.getPointer();
7035+
defaultInfo->ExprType = type;
7036+
}
7037+
70157038
void ParamDecl::setStoredProperty(VarDecl *var) {
70167039
if (!DefaultValueAndFlags.getPointer()) {
70177040
if (!var) return;

lib/AST/TypeCheckRequests.cpp

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1206,6 +1206,27 @@ void DefaultArgumentExprRequest::cacheResult(Expr *expr) const {
12061206
param->setDefaultExpr(expr, /*isTypeChecked*/ true);
12071207
}
12081208

1209+
//----------------------------------------------------------------------------//
1210+
// DefaultArgumentTypeRequest computation.
1211+
//----------------------------------------------------------------------------//
1212+
1213+
Optional<Type> DefaultArgumentTypeRequest::getCachedResult() const {
1214+
auto *param = std::get<0>(getStorage());
1215+
auto *defaultInfo = param->DefaultValueAndFlags.getPointer();
1216+
if (!defaultInfo)
1217+
return None;
1218+
1219+
if (!defaultInfo->InitContextAndIsTypeChecked.getInt())
1220+
return None;
1221+
1222+
return defaultInfo->ExprType;
1223+
}
1224+
1225+
void DefaultArgumentTypeRequest::cacheResult(Type type) const {
1226+
auto *param = std::get<0>(getStorage());
1227+
param->setDefaultExprType(type);
1228+
}
1229+
12091230
//----------------------------------------------------------------------------//
12101231
// CallerSideDefaultArgExprRequest computation.
12111232
//----------------------------------------------------------------------------//

lib/Sema/TypeCheckDeclPrimary.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1063,6 +1063,13 @@ Expr *DefaultArgumentExprRequest::evaluate(Evaluator &evaluator,
10631063
return initExpr;
10641064
}
10651065

1066+
Type DefaultArgumentTypeRequest::evaluate(Evaluator &evaluator,
1067+
ParamDecl *param) const {
1068+
if (auto expr = param->getTypeCheckedDefaultExpr())
1069+
return expr->getType();
1070+
return Type();
1071+
}
1072+
10661073
Initializer *
10671074
DefaultArgumentInitContextRequest::evaluate(Evaluator &eval,
10681075
ParamDecl *param) const {

lib/Serialization/Deserialization.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3246,9 +3246,12 @@ class DeclDeserializer {
32463246
// FIXME: Default argument expression, if available.
32473247
if (auto defaultArg = getActualDefaultArgKind(rawDefaultArg)) {
32483248
param->setDefaultArgumentKind(*defaultArg);
3249+
3250+
if (auto exprType = MF.getType(defaultExprType))
3251+
param->setDefaultExprType(exprType);
3252+
32493253
if (!blobData.empty())
32503254
param->setDefaultValueStringRepresentation(blobData);
3251-
// TODO: Set default expression type.
32523255
}
32533256
return param;
32543257
}

lib/Serialization/Serialization.cpp

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3779,10 +3779,8 @@ class Serializer::DeclSerializer : public DeclVisitor<DeclSerializer> {
37793779
defaultArgumentText =
37803780
param->getDefaultValueStringRepresentation(scratch);
37813781

3782-
if (argKind == swift::DefaultArgumentKind::Normal) {
3783-
if (auto *defaultExpr = param->getTypeCheckedDefaultExpr())
3784-
defaultExprType = defaultExpr->getType();
3785-
}
3782+
// Serialize the type of the default expression (if any).
3783+
defaultExprType = param->getTypeOfDefaultExpr();
37863784
}
37873785

37883786
unsigned abbrCode = S.DeclTypeAbbrCodes[ParamLayout::Code];

0 commit comments

Comments
 (0)