Skip to content

Commit 16c59fa

Browse files
authored
Merge pull request swiftlang#67588 from jckarter/raw-layout-multi-file
Requestify raw layout "like" type resolution.
2 parents c2f0fde + 56f2ae6 commit 16c59fa

File tree

10 files changed

+103
-40
lines changed

10 files changed

+103
-40
lines changed

include/swift/AST/Attr.h

Lines changed: 11 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2496,8 +2496,10 @@ class RawLayoutAttr final : public DeclAttribute {
24962496
/// If `LikeType` is null, the alignment in bytes to use for the raw storage.
24972497
unsigned Alignment;
24982498
/// The resolved like type.
2499-
Type ResolvedLikeType = Type();
2500-
2499+
mutable Type CachedResolvedLikeType = Type();
2500+
2501+
friend class ResolveRawLayoutLikeTypeRequest;
2502+
25012503
public:
25022504
/// Construct a `@_rawLayout(like: T)` attribute.
25032505
RawLayoutAttr(TypeRepr *LikeType,
@@ -2553,32 +2555,29 @@ class RawLayoutAttr final : public DeclAttribute {
25532555
return std::make_pair(SizeOrCount, Alignment);
25542556
}
25552557

2556-
/// Set the resolved type.
2557-
void setResolvedLikeType(Type ty) {
2558-
assert(LikeType && "doesn't have a like type");
2559-
ResolvedLikeType = ty;
2560-
}
2561-
2558+
Type getResolvedLikeType(StructDecl *sd) const;
2559+
25622560
/// Return the type whose single-element layout the attribute type should get
25632561
/// its layout from. Returns None if the attribute specifies an array or manual
25642562
/// layout.
2565-
llvm::Optional<Type> getResolvedScalarLikeType() const {
2563+
llvm::Optional<Type> getResolvedScalarLikeType(StructDecl *sd) const {
25662564
if (!LikeType)
25672565
return llvm::None;
25682566
if (Alignment != ~0u)
25692567
return llvm::None;
2570-
return ResolvedLikeType;
2568+
return getResolvedLikeType(sd);
25712569
}
25722570

25732571
/// Return the type whose array layout the attribute type should get its
25742572
/// layout from, along with the size of that array. Returns None if the
25752573
/// attribute specifies scalar or manual layout.
2576-
llvm::Optional<std::pair<Type, unsigned>> getResolvedArrayLikeTypeAndCount() const {
2574+
llvm::Optional<std::pair<Type, unsigned>>
2575+
getResolvedArrayLikeTypeAndCount(StructDecl *sd) const {
25772576
if (!LikeType)
25782577
return llvm::None;
25792578
if (Alignment == ~0u)
25802579
return llvm::None;
2581-
return std::make_pair(ResolvedLikeType, SizeOrCount);
2580+
return std::make_pair(getResolvedLikeType(sd), SizeOrCount);
25822581
}
25832582

25842583
static bool classof(const DeclAttribute *DA) {

include/swift/AST/TypeCheckRequests.h

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3376,6 +3376,28 @@ class ResolveTypeEraserTypeRequest
33763376
void cacheResult(Type value) const;
33773377
};
33783378

3379+
class ResolveRawLayoutLikeTypeRequest
3380+
: public SimpleRequest<ResolveRawLayoutLikeTypeRequest,
3381+
Type (StructDecl*, RawLayoutAttr *),
3382+
RequestFlags::SeparatelyCached> {
3383+
public:
3384+
using SimpleRequest::SimpleRequest;
3385+
3386+
private:
3387+
friend SimpleRequest;
3388+
3389+
// Evaluation.
3390+
Type evaluate(Evaluator &evaluator,
3391+
StructDecl *sd,
3392+
RawLayoutAttr *attr) const;
3393+
3394+
public:
3395+
// Separate caching.
3396+
bool isCached() const { return true; }
3397+
llvm::Optional<Type> getCachedResult() const;
3398+
void cacheResult(Type value) const;
3399+
};
3400+
33793401
/// Determines whether this is a "simple" didSet i.e one that either does not
33803402
/// use the implicit oldValue parameter in the body or does not take an explicit
33813403
/// parameter (ex: 'didSet(oldValue)').

include/swift/AST/TypeCheckerTypeIDZone.def

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -375,6 +375,9 @@ SWIFT_REQUEST(TypeChecker, ConformanceHasEffectRequest,
375375
SWIFT_REQUEST(TypeChecker, ResolveTypeRequest,
376376
Type (const TypeResolution *, TypeRepr *, GenericParamList *),
377377
Uncached, NoLocationInfo)
378+
SWIFT_REQUEST(TypeChecker, ResolveRawLayoutLikeTypeRequest,
379+
Type(StructDecl *, RawLayoutAttr *),
380+
SeparatelyCached, NoLocationInfo)
378381
SWIFT_REQUEST(TypeChecker, SPIGroupsRequest,
379382
llvm::ArrayRef<Identifier>(Decl *),
380383
Cached, NoLocationInfo)

lib/AST/Attr.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1885,6 +1885,14 @@ Type TypeEraserAttr::getResolvedType(const ProtocolDecl *PD) const {
18851885
ErrorType::get(ctx));
18861886
}
18871887

1888+
Type RawLayoutAttr::getResolvedLikeType(StructDecl *sd) const {
1889+
auto &ctx = sd->getASTContext();
1890+
return evaluateOrDefault(ctx.evaluator,
1891+
ResolveRawLayoutLikeTypeRequest{sd,
1892+
const_cast<RawLayoutAttr *>(this)},
1893+
ErrorType::get(ctx));
1894+
}
1895+
18881896
AvailableAttr *
18891897
AvailableAttr::createPlatformAgnostic(ASTContext &C,
18901898
StringRef Message,

lib/AST/TypeCheckRequests.cpp

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1387,6 +1387,24 @@ void ResolveTypeEraserTypeRequest::cacheResult(Type value) const {
13871387
}
13881388
}
13891389

1390+
//----------------------------------------------------------------------------//
1391+
// ResolveRawLayoutLikeTypeRequest computation.
1392+
//----------------------------------------------------------------------------//
1393+
1394+
llvm::Optional<Type> ResolveRawLayoutLikeTypeRequest::getCachedResult() const {
1395+
auto Ty = std::get<1>(getStorage())->CachedResolvedLikeType;
1396+
if (!Ty) {
1397+
return llvm::None;
1398+
}
1399+
return Ty;
1400+
}
1401+
1402+
void ResolveRawLayoutLikeTypeRequest::cacheResult(Type value) const {
1403+
assert(value && "Resolved type erasure type to null type!");
1404+
auto *attr = std::get<1>(getStorage());
1405+
attr->CachedResolvedLikeType = value;
1406+
}
1407+
13901408
//----------------------------------------------------------------------------//
13911409
// TypeCheckSourceFileRequest computation.
13921410
//----------------------------------------------------------------------------//

lib/IRGen/StructLayout.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@ StructLayout::StructLayout(IRGenModule &IGM,
7474
rawLayout = decl->getAttrs().getAttribute<RawLayoutAttr>();
7575
}
7676
if (rawLayout) {
77+
auto sd = cast<StructDecl>(decl);
7778
IsKnownTriviallyDestroyable = deinit;
7879
IsKnownBitwiseTakable = IsBitwiseTakable;
7980
SpareBits.clear();
@@ -98,7 +99,7 @@ StructLayout::StructLayout(IRGenModule &IGM,
9899
SpareBits.extendWithClearBits(MinimumSize.getValueInBits());
99100
IsFixedLayout = true;
100101
IsKnownAlwaysFixedSize = IsFixedSize;
101-
} else if (auto likeType = rawLayout->getResolvedScalarLikeType()) {
102+
} else if (auto likeType = rawLayout->getResolvedScalarLikeType(sd)) {
102103
const TypeInfo &likeTypeInfo
103104
= IGM.getTypeInfoForUnlowered(AbstractionPattern::getOpaque(),
104105
*likeType);
@@ -116,7 +117,7 @@ StructLayout::StructLayout(IRGenModule &IGM,
116117
IsFixedLayout = false;
117118
IsKnownAlwaysFixedSize = IsNotFixedSize;
118119
}
119-
} else if (auto likeArray = rawLayout->getResolvedArrayLikeTypeAndCount()) {
120+
} else if (auto likeArray = rawLayout->getResolvedArrayLikeTypeAndCount(sd)) {
120121
auto elementType = likeArray->first;
121122
unsigned count = likeArray->second;
122123

lib/Sema/TypeCheckAttr.cpp

Lines changed: 20 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -3366,6 +3366,22 @@ ResolveTypeEraserTypeRequest::evaluate(Evaluator &evaluator,
33663366
}
33673367
}
33683368

3369+
Type
3370+
ResolveRawLayoutLikeTypeRequest::evaluate(Evaluator &evaluator,
3371+
StructDecl *sd,
3372+
RawLayoutAttr *attr) const {
3373+
assert(attr->LikeType);
3374+
// Resolve the like type in the struct's context.
3375+
return TypeResolution::resolveContextualType(
3376+
attr->LikeType, sd, llvm::None,
3377+
// Unbound generics and placeholders
3378+
// are not allowed within this
3379+
// attribute.
3380+
/*unboundTyOpener*/ nullptr,
3381+
/*placeholderHandler*/ nullptr,
3382+
/*packElementOpener*/ nullptr);
3383+
}
3384+
33693385
bool
33703386
TypeEraserHasViableInitRequest::evaluate(Evaluator &evaluator,
33713387
TypeEraserAttr *attr,
@@ -7195,30 +7211,10 @@ void AttributeChecker::visitRawLayoutAttr(RawLayoutAttr *attr) {
71957211
diagnoseAndRemoveAttr(attr, diag::alignment_not_power_of_two);
71967212
return;
71977213
}
7198-
} else if (auto likeType = attr->getScalarLikeType()) {
7199-
// Resolve the like type in the struct's context.
7200-
auto resolvedType = TypeResolution::resolveContextualType(
7201-
likeType, sd, llvm::None,
7202-
// Unbound generics and placeholders
7203-
// are not allowed within this
7204-
// attribute.
7205-
/*unboundTyOpener*/ nullptr,
7206-
/*placeholderHandler*/ nullptr,
7207-
/*packElementOpener*/ nullptr);
7208-
7209-
attr->setResolvedLikeType(resolvedType);
7210-
} else if (auto arrayType = attr->getArrayLikeTypeAndCount()) {
7211-
// Resolve the like type in the struct's context.
7212-
auto resolvedType = TypeResolution::resolveContextualType(
7213-
arrayType->first, sd, llvm::None,
7214-
// Unbound generics and placeholders
7215-
// are not allowed within this
7216-
// attribute.
7217-
/*unboundTyOpener*/ nullptr,
7218-
/*placeholderHandler*/ nullptr,
7219-
/*packElementOpener*/ nullptr);
7220-
7221-
attr->setResolvedLikeType(resolvedType);
7214+
} else if (attr->getScalarLikeType()) {
7215+
(void)attr->getResolvedLikeType(sd);
7216+
} else if (attr->getArrayLikeTypeAndCount()) {
7217+
(void)attr->getResolvedLikeType(sd);
72227218
} else {
72237219
llvm_unreachable("new unhandled rawLayout attribute form?");
72247220
}

lib/Serialization/Serialization.cpp

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3199,15 +3199,19 @@ class Serializer::DeclSerializer : public DeclVisitor<DeclSerializer> {
31993199
uint8_t rawAlign;
32003200
TypeID typeID;
32013201

3202+
auto SD = const_cast<StructDecl*>(cast<StructDecl>(D));
3203+
32023204
if (auto sizeAndAlign = attr->getSizeAndAlignment()) {
32033205
typeID = 0;
32043206
rawSize = sizeAndAlign->first;
32053207
rawAlign = sizeAndAlign->second;
3206-
} else if (auto likeType = attr->getResolvedScalarLikeType()) {
3208+
} else if (auto likeType
3209+
= attr->getResolvedScalarLikeType(SD)) {
32073210
typeID = S.addTypeRef(*likeType);
32083211
rawSize = 0;
32093212
rawAlign = 0;
3210-
} else if (auto likeArrayTypeAndCount = attr->getResolvedArrayLikeTypeAndCount()) {
3213+
} else if (auto likeArrayTypeAndCount
3214+
= attr->getResolvedArrayLikeTypeAndCount(SD)) {
32113215
typeID = S.addTypeRef(likeArrayTypeAndCount->first);
32123216
rawSize = likeArrayTypeAndCount->second;
32133217
rawAlign = static_cast<uint8_t>(~0u);
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
extension Foo where T == Int32 {
2+
3+
}
4+
5+
public func foo(_: borrowing Foo<Int32>) {}

test/IRGen/raw_layout_multifile.swift

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
// RUN: %target-swift-frontend -enable-experimental-feature RawLayout -emit-ir -primary-file %s %S/Inputs/raw_layout_multifile_b.swift
2+
// RUN: %target-swift-frontend -enable-experimental-feature RawLayout -emit-ir %s -primary-file %S/Inputs/raw_layout_multifile_b.swift
3+
4+
import Swift
5+
6+
@_rawLayout(like: Int32)
7+
public struct Foo<T>: ~Copyable {}

0 commit comments

Comments
 (0)