Skip to content

Commit f5dc508

Browse files
committed
SILGen default argument generators for enum cases
1 parent a811303 commit f5dc508

17 files changed

+130
-35
lines changed

include/swift/AST/ASTMangler.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ class ASTMangler : public Mangler {
9191
std::string mangleGlobalGetterEntity(const ValueDecl *decl,
9292
SymbolKind SKind = SymbolKind::Default);
9393

94-
std::string mangleDefaultArgumentEntity(const DeclContext *func,
94+
std::string mangleDefaultArgumentEntity(const ValueDecl *decl,
9595
unsigned index,
9696
SymbolKind SKind);
9797

include/swift/AST/Decl.h

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -351,14 +351,14 @@ class alignas(1 << DeclAlignInBits) Decl {
351351
);
352352

353353
SWIFT_INLINE_BITFIELD(EnumElementDecl, ValueDecl, 3,
354-
/// \brief Whether or not this element has an associated value.
355-
HasArgumentType : 1,
354+
/// \brief The ResilienceExpansion to use for default arguments.
355+
DefaultArgumentResilienceExpansion : 1,
356356

357357
/// \brief Whether or not this element directly or indirectly references
358358
/// the enum type.
359359
Recursiveness : 2
360360
);
361-
361+
362362
SWIFT_INLINE_BITFIELD(AbstractFunctionDecl, ValueDecl, 3+8+5+1+1+1+1+1,
363363
/// \see AbstractFunctionDecl::BodyKind
364364
BodyKind : 3,
@@ -5758,6 +5758,8 @@ class EnumElementDecl : public ValueDecl {
57585758
{
57595759
Bits.EnumElementDecl.Recursiveness =
57605760
static_cast<unsigned>(ElementRecursiveness::NotRecursive);
5761+
EnumElementDeclBits.DefaultArgumentResilienceExpansion =
5762+
static_cast<unsigned>(ResilienceExpansion::Maximal);
57615763
}
57625764

57635765
Identifier getName() const { return getFullName().getBaseIdentifier(); }
@@ -5809,6 +5811,21 @@ class EnumElementDecl : public ValueDecl {
58095811
Bits.EnumElementDecl.Recursiveness = static_cast<unsigned>(recursiveness);
58105812
}
58115813

5814+
/// The ResilienceExpansion for default arguments.
5815+
///
5816+
/// In Swift 4 mode, default argument expressions are serialized, and must
5817+
/// obey the restrictions imposed upon inlineable function bodies.
5818+
ResilienceExpansion getDefaultArgumentResilienceExpansion() const {
5819+
return ResilienceExpansion(
5820+
EnumElementDeclBits.DefaultArgumentResilienceExpansion);
5821+
}
5822+
5823+
/// Set the ResilienceExpansion for default arguments.
5824+
void setDefaultArgumentResilienceExpansion(ResilienceExpansion expansion) {
5825+
EnumElementDeclBits.DefaultArgumentResilienceExpansion =
5826+
unsigned(expansion);
5827+
}
5828+
58125829
bool hasAssociatedValues() const {
58135830
return getParameterList() != nullptr;
58145831
}
@@ -6677,7 +6694,7 @@ inline EnumElementDecl *EnumDecl::getUniqueElement(bool hasValue) const {
66776694
/// \returns the default argument kind and, if there is a default argument,
66786695
/// the type of the corresponding parameter.
66796696
std::pair<DefaultArgumentKind, Type>
6680-
getDefaultArgumentInfo(ValueDecl *source, unsigned Index);
6697+
getDefaultArgumentInfo(ArrayRef<const ParameterList *> paramLists, unsigned Index);
66816698

66826699
} // end namespace swift
66836700

include/swift/Serialization/ModuleFormat.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1080,6 +1080,7 @@ namespace decls_block {
10801080
EnumElementRawValueKindField, // raw value kind
10811081
BCFixed<1>, // negative raw value?
10821082
IdentifierIDField, // raw value
1083+
BCFixed<1>, // default argument resilience expansion
10831084
BCVBR<5>, // number of parameter name components
10841085
BCArray<IdentifierIDField> // name components,
10851086

lib/AST/ASTMangler.cpp

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -159,11 +159,15 @@ std::string ASTMangler::mangleGlobalGetterEntity(const ValueDecl *decl,
159159
return finalize();
160160
}
161161

162-
std::string ASTMangler::mangleDefaultArgumentEntity(const DeclContext *func,
162+
std::string ASTMangler::mangleDefaultArgumentEntity(const ValueDecl *decl,
163163
unsigned index,
164164
SymbolKind SKind) {
165165
beginMangling();
166-
appendDefaultArgumentEntity(func, index);
166+
if (auto *AFD = dyn_cast<AbstractFunctionDecl>(decl)) {
167+
appendDefaultArgumentEntity(AFD, index);
168+
} else {
169+
appendDefaultArgumentEntity(decl->getDeclContext(), index);
170+
}
167171
appendSymbolKind(SKind);
168172
return finalize();
169173
}

lib/AST/Decl.cpp

Lines changed: 2 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -4682,18 +4682,8 @@ ParamDecl *AbstractFunctionDecl::getImplicitSelfDecl() {
46824682
}
46834683

46844684
std::pair<DefaultArgumentKind, Type>
4685-
swift::getDefaultArgumentInfo(ValueDecl *source, unsigned Index) {
4686-
ArrayRef<const ParameterList *> paramLists;
4687-
if (auto *AFD = dyn_cast<AbstractFunctionDecl>(source)) {
4688-
paramLists = AFD->getParameterLists();
4689-
4690-
// Skip the 'self' parameter; it is not counted.
4691-
if (AFD->getImplicitSelfDecl())
4692-
paramLists = paramLists.slice(1);
4693-
} else {
4694-
paramLists = cast<EnumElementDecl>(source)->getParameterList();
4695-
}
4696-
4685+
swift::getDefaultArgumentInfo(ArrayRef<const ParameterList *> paramLists,
4686+
unsigned Index) {
46974687
for (auto paramList : paramLists) {
46984688
if (Index < paramList->size()) {
46994689
auto param = paramList->get(Index);

lib/AST/DeclContext.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -333,6 +333,9 @@ ResilienceExpansion DeclContext::getResilienceExpansion() const {
333333
// Default argument initializer contexts have their resilience expansion
334334
// set when they're type checked.
335335
if (isa<DefaultArgumentInitializer>(dc)) {
336+
if (auto *ED = dyn_cast<EnumDecl>(dc->getParent())) {
337+
return ED->getResilienceExpansion();
338+
}
336339
return cast<AbstractFunctionDecl>(dc->getParent())
337340
->getDefaultArgumentResilienceExpansion();
338341
}

lib/SIL/SILDeclRef.cpp

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -412,8 +412,14 @@ IsSerialized_t SILDeclRef::isSerialized() const {
412412
// Default argument generators are serialized if the function was
413413
// type-checked in Swift 4 mode.
414414
if (kind == SILDeclRef::Kind::DefaultArgGenerator) {
415-
auto *afd = cast<AbstractFunctionDecl>(d);
416-
switch (afd->getDefaultArgumentResilienceExpansion()) {
415+
ResilienceExpansion expansion;
416+
if (auto *EED = dyn_cast<EnumElementDecl>(d)) {
417+
expansion = EED->getDefaultArgumentResilienceExpansion();
418+
} else {
419+
expansion = cast<AbstractFunctionDecl>(d)
420+
->getDefaultArgumentResilienceExpansion();
421+
}
422+
switch (expansion) {
417423
case ResilienceExpansion::Minimal:
418424
return IsSerialized;
419425
case ResilienceExpansion::Maximal:
@@ -660,10 +666,8 @@ std::string SILDeclRef::mangle(ManglingKind MKind) const {
660666

661667
case SILDeclRef::Kind::DefaultArgGenerator:
662668
assert(!isCurried);
663-
return mangler.mangleDefaultArgumentEntity(
664-
cast<AbstractFunctionDecl>(getDecl()),
665-
defaultArgIndex,
666-
SKind);
669+
return mangler.mangleDefaultArgumentEntity(getDecl(), defaultArgIndex,
670+
SKind);
667671

668672
case SILDeclRef::Kind::StoredPropertyInitializer:
669673
assert(!isCurried);

lib/SIL/TypeLowering.cpp

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1725,7 +1725,20 @@ static CanAnyFunctionType getDefaultArgGeneratorInterfaceType(
17251725
ValueDecl *VD,
17261726
DeclContext *DC,
17271727
unsigned DefaultArgIndex) {
1728-
auto resultTy = getDefaultArgumentInfo(VD, DefaultArgIndex).second;
1728+
Type resultTy;
1729+
if (auto *AFD = dyn_cast<AbstractFunctionDecl>(VD)) {
1730+
ArrayRef<const ParameterList *> paramLists = AFD->getParameterLists();
1731+
1732+
// Skip the 'self' parameter; it is not counted.
1733+
if (AFD->getImplicitSelfDecl())
1734+
paramLists = paramLists.slice(1);
1735+
1736+
resultTy = getDefaultArgumentInfo(paramLists, DefaultArgIndex).second;
1737+
} else {
1738+
resultTy = getDefaultArgumentInfo(
1739+
cast<EnumElementDecl>(VD)->getParameterList(),
1740+
DefaultArgIndex).second;
1741+
}
17291742
assert(resultTy && "Didn't find default argument?");
17301743

17311744
// The result type might be written in terms of type parameters

lib/SILGen/ArgumentSource.h

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -223,7 +223,17 @@ class ArgumentSource {
223223
bool isRValue() const & { return StoredKind == Kind::RValue; }
224224
bool isLValue() const & { return StoredKind == Kind::LValue; }
225225
bool isTuple() const & { return StoredKind == Kind::Tuple; }
226-
226+
bool isTupleShuffleExpr() const & {
227+
if (StoredKind == Kind::Expr) {
228+
if (auto *TSE = dyn_cast<TupleShuffleExpr>(asKnownExpr())) {
229+
return llvm::any_of(TSE->getElementMapping(), [](const int &i) {
230+
return i == TupleShuffleExpr::DefaultInitialize;
231+
});
232+
}
233+
}
234+
return false;
235+
}
236+
227237
/// Given that this source is storing an RValue, extract and clear
228238
/// that value.
229239
RValue &&asKnownRValue(SILGenFunction &SGF) && {

lib/SILGen/SILGen.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -788,6 +788,9 @@ void SILGenModule::emitConstructor(ConstructorDecl *decl) {
788788
void SILGenModule::emitEnumConstructor(EnumElementDecl *decl) {
789789
// Enum element constructors are always emitted by need, so don't need
790790
// delayed emission.
791+
if (auto params = decl->getParameterList())
792+
emitDefaultArgGenerators(decl, params);
793+
791794
SILDeclRef constant(decl);
792795
SILFunction *f = getFunction(constant, ForDefinition);
793796
preEmitFunction(constant, decl, f, decl);

lib/SILGen/SILGenApply.cpp

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -647,8 +647,11 @@ class Callee {
647647
auto constantInfo = SGF.getConstantInfo(*constant);
648648
return createCalleeTypeInfo(SGF, constant, constantInfo.getSILType());
649649
}
650-
case Kind::EnumElement:
651-
llvm_unreachable("Should have been curried");
650+
case Kind::EnumElement: {
651+
// Emit a direct call to the element constructor thunk.
652+
auto constantInfo = SGF.getConstantInfo(*constant);
653+
return createCalleeTypeInfo(SGF, constant, constantInfo.getSILType());
654+
}
652655
case Kind::ClassMethod: {
653656
auto constantInfo = SGF.SGM.Types.getConstantOverrideInfo(*constant);
654657
return createCalleeTypeInfo(SGF, constant, constantInfo.getSILType());
@@ -3478,6 +3481,10 @@ class CallEmission {
34783481
extraSites.push_back(std::move(site));
34793482
}
34803483

3484+
bool isArgTupleShuffle() const {
3485+
return ArgValue.isTupleShuffleExpr();
3486+
}
3487+
34813488
/// Add a level of function application by passing in its possibly
34823489
/// unevaluated arguments and their formal type
34833490
template<typename...T>
@@ -3632,7 +3639,10 @@ CallEmission::applyFirstLevelCallee(SGFContext C) {
36323639
return applyPartiallyAppliedSuperMethod(C);
36333640
}
36343641

3635-
if (isEnumElementConstructor()) {
3642+
3643+
if (isEnumElementConstructor() && llvm::all_of(uncurriedSites, [](const CallSite &s){
3644+
return !s.isArgTupleShuffle();
3645+
})) {
36363646
return applyEnumElementConstructor(C);
36373647
}
36383648

lib/SILGen/SILGenFunction.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,9 @@ DeclName SILGenModule::getMagicFunctionName(SILDeclRef ref) {
110110
case SILDeclRef::Kind::GlobalAccessor:
111111
return getMagicFunctionName(cast<VarDecl>(ref.getDecl())->getDeclContext());
112112
case SILDeclRef::Kind::DefaultArgGenerator:
113+
if (auto *ED = dyn_cast<EnumElementDecl>(ref.getDecl())) {
114+
return ED->getFullName();
115+
}
113116
return getMagicFunctionName(cast<AbstractFunctionDecl>(ref.getDecl()));
114117
case SILDeclRef::Kind::StoredPropertyInitializer:
115118
return getMagicFunctionName(cast<VarDecl>(ref.getDecl())->getDeclContext());

lib/Sema/CSApply.cpp

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4965,7 +4965,20 @@ getCallerDefaultArg(ConstraintSystem &cs, DeclContext *dc,
49654965
unsigned index) {
49664966
auto &tc = cs.getTypeChecker();
49674967

4968-
auto defArg = getDefaultArgumentInfo(cast<ValueDecl>(owner.getDecl()), index);
4968+
std::pair<DefaultArgumentKind, Type> defArg;
4969+
if (auto *AFD = dyn_cast<AbstractFunctionDecl>(owner.getDecl())) {
4970+
auto paramLists = AFD->getParameterLists();
4971+
4972+
// Skip the 'self' parameter; it is not counted.
4973+
if (AFD->getImplicitSelfDecl())
4974+
paramLists = paramLists.slice(1);
4975+
4976+
defArg = getDefaultArgumentInfo(paramLists, index);
4977+
} else {
4978+
defArg = getDefaultArgumentInfo(
4979+
cast<EnumElementDecl>(owner.getDecl())->getParameterList(),
4980+
index);
4981+
}
49694982
Expr *init = nullptr;
49704983
switch (defArg.first) {
49714984
case DefaultArgumentKind::None:

lib/Sema/TypeCheckStmt.cpp

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1347,8 +1347,7 @@ Stmt *StmtChecker::visitBraceStmt(BraceStmt *BS) {
13471347
/// Check the default arguments that occur within this pattern.
13481348
static void checkDefaultArguments(TypeChecker &tc,
13491349
ParameterList *params,
1350-
unsigned &nextArgIndex,
1351-
AbstractFunctionDecl *func) {
1350+
unsigned &nextArgIndex) {
13521351
for (auto &param : *params) {
13531352
++nextArgIndex;
13541353
if (!param->getDefaultValue() || !param->hasType() ||
@@ -1389,11 +1388,20 @@ void TypeChecker::checkDefaultArguments(ArrayRef<ParameterList *> paramLists,
13891388
expansion = ResilienceExpansion::Minimal;
13901389

13911390
func->setDefaultArgumentResilienceExpansion(expansion);
1391+
} else {
1392+
auto *EED = cast<EnumElementDecl>(VD);
1393+
auto expansion = EED->getParentEnum()->getResilienceExpansion();
1394+
if (!Context.isSwiftVersion3() &&
1395+
EED->getFormalAccessScope(/*useDC=*/nullptr,
1396+
/*respectVersionedAttr=*/true).isPublic())
1397+
expansion = ResilienceExpansion::Minimal;
1398+
1399+
EED->setDefaultArgumentResilienceExpansion(expansion);
13921400
}
13931401

13941402
unsigned nextArgIndex = 0;
13951403
for (auto *paramList : paramLists)
1396-
checkDefaultArguments(*this, paramList, nextArgIndex, func);
1404+
::checkDefaultArguments(*this, paramList, nextArgIndex);
13971405
}
13981406

13991407
bool TypeChecker::typeCheckAbstractFunctionBodyUntil(AbstractFunctionDecl *AFD,

lib/Sema/TypeCheckType.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1428,7 +1428,7 @@ static Type applyNonEscapingFromContext(DeclContext *DC,
14281428
bool defaultNoEscape =
14291429
!options.contains(TypeResolutionFlags::EnumCase) &&
14301430
(options.contains(TypeResolutionFlags::FunctionInput) ||
1431-
options.contains(TypeResolutionFlags::ImmediateFunctionInput);
1431+
options.contains(TypeResolutionFlags::ImmediateFunctionInput));
14321432

14331433
// Desugar here
14341434
auto *funcTy = ty->castTo<FunctionType>();

lib/Serialization/Deserialization.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3722,6 +3722,7 @@ ModuleFile::getDeclCheckedImpl(DeclID DID, Optional<DeclContext *> ForcedContext
37223722
bool isImplicit; bool isNegative;
37233723
unsigned rawValueKindID;
37243724
IdentifierID blobData;
3725+
uint8_t rawDefaultArgumentResilienceExpansion;
37253726
unsigned numArgNames;
37263727
ArrayRef<uint64_t> argNameAndDependencyIDs;
37273728

@@ -3730,6 +3731,7 @@ ModuleFile::getDeclCheckedImpl(DeclID DID, Optional<DeclContext *> ForcedContext
37303731
isImplicit, rawValueKindID,
37313732
isNegative,
37323733
blobData,
3734+
rawDefaultArgumentResilienceExpansion,
37333735
numArgNames,
37343736
argNameAndDependencyIDs);
37353737

@@ -3783,6 +3785,15 @@ ModuleFile::getDeclCheckedImpl(DeclID DID, Optional<DeclContext *> ForcedContext
37833785
elem->setAccess(std::max(cast<EnumDecl>(DC)->getFormalAccess(),
37843786
AccessLevel::Internal));
37853787

3788+
if (auto defaultArgumentResilienceExpansion = getActualResilienceExpansion(
3789+
rawDefaultArgumentResilienceExpansion)) {
3790+
elem->setDefaultArgumentResilienceExpansion(
3791+
*defaultArgumentResilienceExpansion);
3792+
} else {
3793+
error();
3794+
return nullptr;
3795+
}
3796+
37863797
break;
37873798
}
37883799

lib/Serialization/Serialization.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3309,6 +3309,10 @@ void Serializer::writeDecl(const Decl *D) {
33093309
Negative = ILE->isNegative();
33103310
}
33113311

3312+
uint8_t rawDefaultArgumentResilienceExpansion =
3313+
getRawStableResilienceExpansion(
3314+
elem->getDefaultArgumentResilienceExpansion());
3315+
33123316
unsigned abbrCode = DeclTypeAbbrCodes[EnumElementLayout::Code];
33133317
EnumElementLayout::emitRecord(Out, ScratchRecord, abbrCode,
33143318
contextID,
@@ -3317,6 +3321,7 @@ void Serializer::writeDecl(const Decl *D) {
33173321
(unsigned)RawValueKind,
33183322
Negative,
33193323
addDeclBaseNameRef(RawValueText),
3324+
rawDefaultArgumentResilienceExpansion,
33203325
elem->getFullName().getArgumentNames().size()+1,
33213326
nameComponentsAndDependencies);
33223327
if (auto *PL = elem->getParameterList())

0 commit comments

Comments
 (0)