Skip to content

Commit 52def21

Browse files
committed
Add LifetimeDependenceInfo into function type
1 parent 0cb805b commit 52def21

File tree

8 files changed

+137
-55
lines changed

8 files changed

+137
-55
lines changed

include/swift/AST/ExtInfo.h

+59-32
Original file line numberDiff line numberDiff line change
@@ -390,42 +390,47 @@ class ASTExtInfoBuilder {
390390
unsigned bits; // Naturally sized for speed.
391391

392392
ClangTypeInfo clangTypeInfo;
393+
393394
Type globalActor;
394395
Type thrownError;
395396

397+
LifetimeDependenceInfo lifetimeDependenceInfo;
398+
396399
using Representation = FunctionTypeRepresentation;
397400

398-
ASTExtInfoBuilder(
399-
unsigned bits, ClangTypeInfo clangTypeInfo, Type globalActor,
400-
Type thrownError
401-
) : bits(bits), clangTypeInfo(clangTypeInfo), globalActor(globalActor),
402-
thrownError(thrownError) {}
401+
ASTExtInfoBuilder(unsigned bits, ClangTypeInfo clangTypeInfo,
402+
Type globalActor, Type thrownError,
403+
LifetimeDependenceInfo lifetimeDependenceInfo)
404+
: bits(bits), clangTypeInfo(clangTypeInfo), globalActor(globalActor),
405+
thrownError(thrownError),
406+
lifetimeDependenceInfo(lifetimeDependenceInfo) {}
403407

404408
public:
405409
/// An ExtInfoBuilder for a typical Swift function: @convention(swift),
406410
/// @escaping, non-throwing, non-differentiable.
407411
ASTExtInfoBuilder()
408412
: ASTExtInfoBuilder(Representation::Swift, false, false, Type(),
409413
DifferentiabilityKind::NonDifferentiable, nullptr,
410-
Type()) {}
414+
Type(), LifetimeDependenceInfo()) {}
411415

412416
// Constructor for polymorphic type.
413417
ASTExtInfoBuilder(Representation rep, bool throws, Type thrownError)
414418
: ASTExtInfoBuilder(rep, false, throws, thrownError,
415419
DifferentiabilityKind::NonDifferentiable, nullptr,
416-
Type()) {}
420+
Type(), LifetimeDependenceInfo()) {}
417421

418422
// Constructor with no defaults.
419423
ASTExtInfoBuilder(Representation rep, bool isNoEscape, bool throws,
420-
Type thrownError,
421-
DifferentiabilityKind diffKind, const clang::Type *type,
422-
Type globalActor)
424+
Type thrownError, DifferentiabilityKind diffKind,
425+
const clang::Type *type, Type globalActor,
426+
LifetimeDependenceInfo lifetimeDependenceInfo)
423427
: ASTExtInfoBuilder(
424428
((unsigned)rep) | (isNoEscape ? NoEscapeMask : 0) |
425429
(throws ? ThrowsMask : 0) |
426430
(((unsigned)diffKind << DifferentiabilityMaskOffset) &
427431
DifferentiabilityMask),
428-
ClangTypeInfo(type), globalActor, thrownError) {}
432+
ClangTypeInfo(type), globalActor, thrownError,
433+
lifetimeDependenceInfo) {}
429434

430435
void checkInvariants() const;
431436

@@ -465,6 +470,10 @@ class ASTExtInfoBuilder {
465470
Type getGlobalActor() const { return globalActor; }
466471
Type getThrownError() const { return thrownError; }
467472

473+
LifetimeDependenceInfo getLifetimeDependenceInfo() const {
474+
return lifetimeDependenceInfo;
475+
}
476+
468477
constexpr bool hasSelfParam() const {
469478
switch (getSILRepresentation()) {
470479
case SILFunctionTypeRepresentation::Thick:
@@ -498,31 +507,31 @@ class ASTExtInfoBuilder {
498507
return ASTExtInfoBuilder((bits & ~RepresentationMask) | (unsigned)rep,
499508
shouldStoreClangType(rep) ? clangTypeInfo
500509
: ClangTypeInfo(),
501-
globalActor, thrownError);
510+
globalActor, thrownError, lifetimeDependenceInfo);
502511
}
503512
[[nodiscard]]
504513
ASTExtInfoBuilder withNoEscape(bool noEscape = true) const {
505-
return ASTExtInfoBuilder(noEscape ? (bits | NoEscapeMask)
506-
: (bits & ~NoEscapeMask),
507-
clangTypeInfo, globalActor, thrownError);
514+
return ASTExtInfoBuilder(
515+
noEscape ? (bits | NoEscapeMask) : (bits & ~NoEscapeMask),
516+
clangTypeInfo, globalActor, thrownError, lifetimeDependenceInfo);
508517
}
509518
[[nodiscard]]
510519
ASTExtInfoBuilder withConcurrent(bool concurrent = true) const {
511-
return ASTExtInfoBuilder(concurrent ? (bits | SendableMask)
512-
: (bits & ~SendableMask),
513-
clangTypeInfo, globalActor, thrownError);
520+
return ASTExtInfoBuilder(
521+
concurrent ? (bits | SendableMask) : (bits & ~SendableMask),
522+
clangTypeInfo, globalActor, thrownError, lifetimeDependenceInfo);
514523
}
515524
[[nodiscard]]
516525
ASTExtInfoBuilder withAsync(bool async = true) const {
517-
return ASTExtInfoBuilder(async ? (bits | AsyncMask)
518-
: (bits & ~AsyncMask),
519-
clangTypeInfo, globalActor, thrownError);
526+
return ASTExtInfoBuilder(async ? (bits | AsyncMask) : (bits & ~AsyncMask),
527+
clangTypeInfo, globalActor, thrownError,
528+
lifetimeDependenceInfo);
520529
}
521530
[[nodiscard]]
522531
ASTExtInfoBuilder withThrows(bool throws, Type thrownError) const {
523532
return ASTExtInfoBuilder(
524533
throws ? (bits | ThrowsMask) : (bits & ~ThrowsMask), clangTypeInfo,
525-
globalActor, thrownError);
534+
globalActor, thrownError, lifetimeDependenceInfo);
526535
}
527536
[[nodiscard]]
528537
ASTExtInfoBuilder withThrows() const {
@@ -534,12 +543,12 @@ class ASTExtInfoBuilder {
534543
return ASTExtInfoBuilder(
535544
(bits & ~DifferentiabilityMask) |
536545
((unsigned)differentiability << DifferentiabilityMaskOffset),
537-
clangTypeInfo, globalActor, thrownError);
546+
clangTypeInfo, globalActor, thrownError, lifetimeDependenceInfo);
538547
}
539548
[[nodiscard]]
540549
ASTExtInfoBuilder withClangFunctionType(const clang::Type *type) const {
541-
return ASTExtInfoBuilder(
542-
bits, ClangTypeInfo(type), globalActor, thrownError);
550+
return ASTExtInfoBuilder(bits, ClangTypeInfo(type), globalActor,
551+
thrownError, lifetimeDependenceInfo);
543552
}
544553

545554
/// Put a SIL representation in the ExtInfo.
@@ -553,19 +562,27 @@ class ASTExtInfoBuilder {
553562
return ASTExtInfoBuilder((bits & ~RepresentationMask) | (unsigned)rep,
554563
shouldStoreClangType(rep) ? clangTypeInfo
555564
: ClangTypeInfo(),
556-
globalActor, thrownError);
565+
globalActor, thrownError, lifetimeDependenceInfo);
557566
}
558567

559568
[[nodiscard]]
560569
ASTExtInfoBuilder withGlobalActor(Type globalActor) const {
561-
return ASTExtInfoBuilder(bits, clangTypeInfo, globalActor, thrownError);
570+
return ASTExtInfoBuilder(bits, clangTypeInfo, globalActor, thrownError,
571+
lifetimeDependenceInfo);
572+
}
573+
574+
[[nodiscard]] ASTExtInfoBuilder withLifetimeDependenceInfo(
575+
LifetimeDependenceInfo lifetimeDependenceInfo) const {
576+
return ASTExtInfoBuilder(bits, clangTypeInfo, globalActor, thrownError,
577+
lifetimeDependenceInfo);
562578
}
563579

564580
bool isEqualTo(ASTExtInfoBuilder other, bool useClangTypes) const {
565581
return bits == other.bits &&
566-
(useClangTypes ? (clangTypeInfo == other.clangTypeInfo) : true) &&
567-
globalActor.getPointer() == other.globalActor.getPointer() &&
568-
thrownError.getPointer() == other.thrownError.getPointer();
582+
(useClangTypes ? (clangTypeInfo == other.clangTypeInfo) : true) &&
583+
globalActor.getPointer() == other.globalActor.getPointer() &&
584+
thrownError.getPointer() == other.thrownError.getPointer() &&
585+
lifetimeDependenceInfo == other.lifetimeDependenceInfo;
569586
}
570587

571588
constexpr std::tuple<unsigned, const void *, const void *, const void *>
@@ -594,8 +611,9 @@ class ASTExtInfo {
594611
ASTExtInfo(ASTExtInfoBuilder builder) : builder(builder) {}
595612

596613
ASTExtInfo(unsigned bits, ClangTypeInfo clangTypeInfo, Type globalActor,
597-
Type thrownError)
598-
: builder(bits, clangTypeInfo, globalActor, thrownError) {
614+
Type thrownError, LifetimeDependenceInfo lifetimeDependenceInfo)
615+
: builder(bits, clangTypeInfo, globalActor, thrownError,
616+
lifetimeDependenceInfo) {
599617
builder.checkInvariants();
600618
};
601619

@@ -642,6 +660,10 @@ class ASTExtInfo {
642660
Type getGlobalActor() const { return builder.getGlobalActor(); }
643661
Type getThrownError() const { return builder.getThrownError(); }
644662

663+
LifetimeDependenceInfo getLifetimeDependenceInfo() const {
664+
return builder.getLifetimeDependenceInfo();
665+
}
666+
645667
/// Helper method for changing the representation.
646668
///
647669
/// Prefer using \c ASTExtInfoBuilder::withRepresentation for chaining.
@@ -695,6 +717,11 @@ class ASTExtInfo {
695717
return builder.withGlobalActor(globalActor).build();
696718
}
697719

720+
[[nodiscard]] ASTExtInfo withLifetimeDependenceInfo(
721+
LifetimeDependenceInfo lifetimeDependenceInfo) const {
722+
return builder.withLifetimeDependenceInfo(lifetimeDependenceInfo).build();
723+
}
724+
698725
bool isEqualTo(ASTExtInfo other, bool useClangTypes) const {
699726
return builder.isEqualTo(other.builder, useClangTypes);
700727
}

include/swift/AST/Types.h

+30-4
Original file line numberDiff line numberDiff line change
@@ -412,14 +412,15 @@ class alignas(1 << TypeAlignInBits) TypeBase
412412

413413
SWIFT_INLINE_BITFIELD_EMPTY(ParenType, SugarType);
414414

415-
SWIFT_INLINE_BITFIELD_FULL(AnyFunctionType, TypeBase, NumAFTExtInfoBits+1+1+1+1+16,
415+
SWIFT_INLINE_BITFIELD_FULL(AnyFunctionType, TypeBase, NumAFTExtInfoBits+1+1+1+1+1+16,
416416
/// Extra information which affects how the function is called, like
417417
/// regparm and the calling convention.
418418
ExtInfoBits : NumAFTExtInfoBits,
419419
HasExtInfo : 1,
420420
HasClangTypeInfo : 1,
421421
HasGlobalActor : 1,
422422
HasThrownError : 1,
423+
HasLifetimeDependenceInfo : 1,
423424
: NumPadBits,
424425
NumParams : 16
425426
);
@@ -3377,6 +3378,8 @@ class AnyFunctionType : public TypeBase {
33773378
!Info.value().getGlobalActor().isNull();
33783379
Bits.AnyFunctionType.HasThrownError =
33793380
!Info.value().getThrownError().isNull();
3381+
Bits.AnyFunctionType.HasLifetimeDependenceInfo =
3382+
!Info.value().getLifetimeDependenceInfo().empty();
33803383
// The use of both assert() and static_assert() is intentional.
33813384
assert(Bits.AnyFunctionType.ExtInfoBits == Info.value().getBits() &&
33823385
"Bits were dropped!");
@@ -3389,6 +3392,7 @@ class AnyFunctionType : public TypeBase {
33893392
Bits.AnyFunctionType.ExtInfoBits = 0;
33903393
Bits.AnyFunctionType.HasGlobalActor = false;
33913394
Bits.AnyFunctionType.HasThrownError = false;
3395+
Bits.AnyFunctionType.HasLifetimeDependenceInfo = false;
33923396
}
33933397
Bits.AnyFunctionType.NumParams = NumParams;
33943398
assert(Bits.AnyFunctionType.NumParams == NumParams && "Params dropped!");
@@ -3435,12 +3439,18 @@ class AnyFunctionType : public TypeBase {
34353439
return Bits.AnyFunctionType.HasThrownError;
34363440
}
34373441

3442+
bool hasLifetimeDependenceInfo() const {
3443+
return Bits.AnyFunctionType.HasLifetimeDependenceInfo;
3444+
}
3445+
34383446
ClangTypeInfo getClangTypeInfo() const;
34393447
ClangTypeInfo getCanonicalClangTypeInfo() const;
34403448

34413449
Type getGlobalActor() const;
34423450
Type getThrownError() const;
34433451

3452+
LifetimeDependenceInfo getLifetimeDependenceInfo() const;
3453+
34443454
/// Retrieve the "effective" thrown interface type, or llvm::None if
34453455
/// this function cannot throw.
34463456
///
@@ -3478,7 +3488,8 @@ class AnyFunctionType : public TypeBase {
34783488
ExtInfo getExtInfo() const {
34793489
assert(hasExtInfo());
34803490
return ExtInfo(Bits.AnyFunctionType.ExtInfoBits, getClangTypeInfo(),
3481-
getGlobalActor(), getThrownError());
3491+
getGlobalActor(), getThrownError(),
3492+
getLifetimeDependenceInfo());
34823493
}
34833494

34843495
/// Get the canonical ExtInfo for the function type.
@@ -3699,7 +3710,8 @@ class FunctionType final
36993710
: public AnyFunctionType,
37003711
public llvm::FoldingSetNode,
37013712
private llvm::TrailingObjects<FunctionType, AnyFunctionType::Param,
3702-
ClangTypeInfo, Type> {
3713+
ClangTypeInfo, Type,
3714+
LifetimeDependenceInfo> {
37033715
friend TrailingObjects;
37043716

37053717

@@ -3715,6 +3727,10 @@ class FunctionType final
37153727
return hasGlobalActor() + hasThrownError();
37163728
}
37173729

3730+
size_t numTrailingObjects(OverloadToken<LifetimeDependenceInfo>) const {
3731+
return hasLifetimeDependenceInfo() ? 1 : 0;
3732+
}
3733+
37183734
public:
37193735
/// 'Constructor' Factory Function
37203736
static FunctionType *get(ArrayRef<Param> params, Type result,
@@ -3745,7 +3761,17 @@ class FunctionType final
37453761
return Type();
37463762
return getTrailingObjects<Type>()[hasGlobalActor()];
37473763
}
3748-
3764+
3765+
LifetimeDependenceInfo getLifetimeDependenceInfo() const {
3766+
if (!hasLifetimeDependenceInfo()) {
3767+
return LifetimeDependenceInfo();
3768+
}
3769+
auto *info = getTrailingObjects<LifetimeDependenceInfo>();
3770+
assert(!info->empty() && "If the LifetimeDependenceInfo was empty, we "
3771+
"shouldn't have stored it.");
3772+
return *info;
3773+
}
3774+
37493775
void Profile(llvm::FoldingSetNodeID &ID) {
37503776
llvm::Optional<ExtInfo> info = llvm::None;
37513777
if (hasExtInfo())

lib/AST/ASTContext.cpp

+13-3
Original file line numberDiff line numberDiff line change
@@ -4209,9 +4209,15 @@ FunctionType *FunctionType::get(ArrayRef<AnyFunctionType::Param> params,
42094209
info.has_value() && !info.value().getClangTypeInfo().empty();
42104210

42114211
unsigned numTypes = (globalActor ? 1 : 0) + (thrownError ? 1 : 0);
4212-
size_t allocSize = totalSizeToAlloc<
4213-
AnyFunctionType::Param, ClangTypeInfo, Type
4214-
>(params.size(), hasClangInfo ? 1 : 0, numTypes);
4212+
4213+
bool hasLifetimeDependenceInfo =
4214+
info.has_value() && !info.value().getLifetimeDependenceInfo().empty();
4215+
4216+
size_t allocSize = totalSizeToAlloc<AnyFunctionType::Param, ClangTypeInfo,
4217+
Type, LifetimeDependenceInfo>(
4218+
params.size(), hasClangInfo ? 1 : 0, numTypes,
4219+
hasLifetimeDependenceInfo ? 1 : 0);
4220+
42154221
void *mem = ctx.Allocate(allocSize, alignof(FunctionType), arena);
42164222

42174223
bool isCanonical = isAnyFunctionTypeCanonical(params, result);
@@ -4257,6 +4263,10 @@ FunctionType::FunctionType(ArrayRef<AnyFunctionType::Param> params, Type output,
42574263
}
42584264
if (Type thrownError = info->getThrownError())
42594265
getTrailingObjects<Type>()[thrownErrorIndex] = thrownError;
4266+
auto lifetimeDependenceInfo = info->getLifetimeDependenceInfo();
4267+
if (!lifetimeDependenceInfo.empty()) {
4268+
*getTrailingObjects<LifetimeDependenceInfo>() = lifetimeDependenceInfo;
4269+
}
42604270
}
42614271
}
42624272

lib/AST/ASTDemangler.cpp

+8-7
Original file line numberDiff line numberDiff line change
@@ -455,13 +455,14 @@ Type ASTBuilder::createFunctionType(
455455
clangFunctionType = Ctx.getClangFunctionType(funcParams, output,
456456
representation);
457457

458-
auto einfo =
459-
FunctionType::ExtInfoBuilder(representation, noescape, flags.isThrowing(),
460-
thrownError, resultDiffKind,
461-
clangFunctionType, globalActor)
462-
.withAsync(flags.isAsync())
463-
.withConcurrent(flags.isSendable())
464-
.build();
458+
// TODO: Handle LifetimeDependenceInfo here.
459+
auto einfo = FunctionType::ExtInfoBuilder(
460+
representation, noescape, flags.isThrowing(), thrownError,
461+
resultDiffKind, clangFunctionType, globalActor,
462+
LifetimeDependenceInfo())
463+
.withAsync(flags.isAsync())
464+
.withConcurrent(flags.isSendable())
465+
.build();
465466

466467
return FunctionType::get(funcParams, output, einfo);
467468
}

lib/AST/Type.cpp

+14-1
Original file line numberDiff line numberDiff line change
@@ -4208,6 +4208,19 @@ Type AnyFunctionType::getGlobalActor() const {
42084208
}
42094209
}
42104210

4211+
LifetimeDependenceInfo AnyFunctionType::getLifetimeDependenceInfo() const {
4212+
switch (getKind()) {
4213+
case TypeKind::Function:
4214+
return cast<FunctionType>(this)->getLifetimeDependenceInfo();
4215+
case TypeKind::GenericFunction:
4216+
// TODO: Handle GenericFunction
4217+
return LifetimeDependenceInfo();
4218+
4219+
default:
4220+
llvm_unreachable("Illegal type kind for AnyFunctionType.");
4221+
}
4222+
}
4223+
42114224
ClangTypeInfo AnyFunctionType::getCanonicalClangTypeInfo() const {
42124225
return getClangTypeInfo().getCanonical();
42134226
}
@@ -4247,7 +4260,7 @@ AnyFunctionType::getCanonicalExtInfo(bool useClangFunctionType) const {
42474260
return ExtInfo(bits,
42484261
useClangFunctionType ? getCanonicalClangTypeInfo()
42494262
: ClangTypeInfo(),
4250-
globalActor, thrownError);
4263+
globalActor, thrownError, getLifetimeDependenceInfo());
42514264
}
42524265

42534266
bool AnyFunctionType::hasNonDerivableClangType() {

lib/Sema/TypeCheckDecl.cpp

+3
Original file line numberDiff line numberDiff line change
@@ -2881,6 +2881,9 @@ InterfaceTypeRequest::evaluate(Evaluator &eval, ValueDecl *D) const {
28812881
// Defer bodies must not escape.
28822882
if (auto fd = dyn_cast<FuncDecl>(D))
28832883
infoBuilder = infoBuilder.withNoEscape(fd->isDeferBody());
2884+
if (lifetimeDependenceInfo.has_value())
2885+
infoBuilder =
2886+
infoBuilder.withLifetimeDependenceInfo(*lifetimeDependenceInfo);
28842887
auto info = infoBuilder.build();
28852888

28862889
if (sig && !hasSelf) {

0 commit comments

Comments
 (0)