Skip to content

Commit 399dd19

Browse files
committed
[WIP] Implement reflection support for Symbolic Extended Existential types.
1 parent 31a9b79 commit 399dd19

File tree

6 files changed

+262
-8
lines changed

6 files changed

+262
-8
lines changed

include/swift/RemoteInspection/TypeRef.h

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -731,6 +731,71 @@ class ConstrainedExistentialTypeRef final : public TypeRef {
731731
}
732732
};
733733

734+
class SymbolicExtendedExistentialTypeRef final : public TypeRef {
735+
remote::RemoteAbsolutePointer Shape;
736+
const ProtocolCompositionTypeRef *Protocol;
737+
std::vector<TypeRefRequirement> Requirements;
738+
std::vector<const TypeRef *> Arguments;
739+
ExtendedExistentialTypeShapeFlags Flags;
740+
741+
static TypeRefID Profile(const remote::RemoteAbsolutePointer Shape,
742+
const ProtocolCompositionTypeRef *Protocol,
743+
llvm::ArrayRef<TypeRefRequirement> Requirements,
744+
llvm::ArrayRef<const TypeRef *> Arguments,
745+
ExtendedExistentialTypeShapeFlags Flags) {
746+
TypeRefID ID;
747+
ID.addString(Shape.getSymbol());
748+
ID.addPointer(Protocol);
749+
for (auto reqt : Requirements) {
750+
ID.addPointer(reqt.getFirstType());
751+
if (reqt.getKind() != RequirementKind::Layout)
752+
ID.addPointer(reqt.getSecondType());
753+
else
754+
ID.addInteger(
755+
unsigned(0)); // FIXME: Layout constraints aren't implemented yet
756+
ID.addInteger(unsigned(reqt.getKind()));
757+
}
758+
759+
for (auto &Arg : Arguments)
760+
ID.addPointer(Arg);
761+
return ID;
762+
}
763+
764+
public:
765+
SymbolicExtendedExistentialTypeRef(
766+
remote::RemoteAbsolutePointer Shape,
767+
const ProtocolCompositionTypeRef *Protocol,
768+
llvm::ArrayRef<TypeRefRequirement> Requirements,
769+
llvm::ArrayRef<const TypeRef *> Args,
770+
ExtendedExistentialTypeShapeFlags Flags)
771+
: TypeRef(TypeRefKind::SymbolicExtendedExistential), Shape(Shape),
772+
Protocol(Protocol), Requirements(Requirements), Arguments(Args),
773+
Flags(Flags) {}
774+
775+
template <typename Allocator>
776+
static const SymbolicExtendedExistentialTypeRef *
777+
create(Allocator &A, remote::RemoteAbsolutePointer Shape,
778+
const ProtocolCompositionTypeRef *Protocol,
779+
llvm::ArrayRef<TypeRefRequirement> Requirements,
780+
llvm::ArrayRef<const TypeRef *> Args,
781+
ExtendedExistentialTypeShapeFlags Flags) {
782+
FIND_OR_CREATE_TYPEREF(A, SymbolicExtendedExistentialTypeRef, Shape,
783+
Protocol, Requirements, Args, Flags);
784+
}
785+
786+
const remote::RemoteAbsolutePointer getShape() const { return Shape; }
787+
const ProtocolCompositionTypeRef *getProtocol() const { return Protocol; }
788+
llvm::ArrayRef<TypeRefRequirement> getRequirements() const {
789+
return Requirements;
790+
}
791+
llvm::ArrayRef<const TypeRef *> getArguments() const { return Arguments; }
792+
ExtendedExistentialTypeShapeFlags getFlags() const { return Flags; }
793+
794+
static bool classof(const TypeRef *TR) {
795+
return TR->getKind() == TypeRefKind::SymbolicExtendedExistential;
796+
}
797+
};
798+
734799
class MetatypeTypeRef final : public TypeRef {
735800
const TypeRef *InstanceType;
736801
bool WasAbstract;

include/swift/RemoteInspection/TypeRefBuilder.h

Lines changed: 60 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1284,7 +1284,56 @@ class TypeRefBuilder {
12841284
createSymbolicExtendedExistentialType(NodePointer shapeNode,
12851285
llvm::ArrayRef<const TypeRef *> args) {
12861286
// Can't handle this here.
1287-
return nullptr;
1287+
1288+
remote::RemoteAddress shape(shapeNode->getIndex());
1289+
auto symbol = OpaquePointerSymbolResolver(shape);
1290+
if (!symbol)
1291+
return nullptr;
1292+
auto bytes = OpaqueByteReader(shape, 4);
1293+
if (!bytes)
1294+
return nullptr;
1295+
ExtendedExistentialTypeShapeFlags flags(*(const uint32_t *)bytes.get());
1296+
1297+
Demangler Dem;
1298+
auto *Node = Dem.demangleSymbol(symbol->getSymbol());
1299+
if (Node->getKind() != Node::Kind::Global || Node->getNumChildren() != 1)
1300+
return nullptr;
1301+
Node = Node->getChild(0);
1302+
if ((Node->getKind() == Node::Kind::Uniquable) &&
1303+
Node->getNumChildren() == 1)
1304+
Node = Node->getChild(0);
1305+
if (Node->getKind() != Node::Kind::ExtendedExistentialTypeShape ||
1306+
Node->getNumChildren() != 2)
1307+
return nullptr;
1308+
Node = Node->getChild(1);
1309+
if (Node->getKind() != Node::Kind::Type || Node->getNumChildren() != 1)
1310+
return nullptr;
1311+
Node = Node->getChild(0);
1312+
if (Node->getKind() != Node::Kind::ConstrainedExistential ||
1313+
Node->getNumChildren() != 2)
1314+
return nullptr;
1315+
auto ReqNode = Node->getChild(1);
1316+
Node = Node->getChild(0);
1317+
if (Node->getKind() != Node::Kind::Type || Node->getNumChildren() != 1)
1318+
return nullptr;
1319+
auto protocol = llvm::dyn_cast_or_null<ProtocolCompositionTypeRef>(
1320+
decodeMangledType(Node));
1321+
if (!protocol)
1322+
return nullptr;
1323+
1324+
if (!ReqNode ||
1325+
ReqNode->getKind() != Node::Kind::ConstrainedExistentialRequirementList)
1326+
return nullptr;
1327+
1328+
llvm::SmallVector<BuiltRequirement, 8> requirements;
1329+
llvm::SmallVector<BuiltInverseRequirement, 8> inverseRequirements;
1330+
1331+
decodeRequirement<BuiltType, BuiltRequirement, BuiltInverseRequirement,
1332+
BuiltLayoutConstraint, TypeRefBuilder>(
1333+
ReqNode, requirements, inverseRequirements, *this);
1334+
1335+
return SymbolicExtendedExistentialTypeRef::create(
1336+
*this, *symbol, protocol, requirements, args, flags);
12881337
}
12891338

12901339
const ExistentialMetatypeTypeRef *createExistentialMetatypeType(
@@ -1312,6 +1361,7 @@ class TypeRefBuilder {
13121361

13131362
const DependentMemberTypeRef *
13141363
createDependentMemberType(const std::string &member, const TypeRef *base) {
1364+
return DependentMemberTypeRef::create(*this, member, base, "");
13151365
// Should not have unresolved dependent member types here.
13161366
return nullptr;
13171367
}
@@ -1479,6 +1529,9 @@ class TypeRefBuilder {
14791529
using PointerReader =
14801530
std::function<std::optional<remote::RemoteAbsolutePointer>(
14811531
remote::RemoteAddress, unsigned)>;
1532+
using PointerSymbolResolver =
1533+
std::function<std::optional<remote::RemoteAbsolutePointer>(
1534+
remote::RemoteAddress)>;
14821535
using DynamicSymbolResolver =
14831536
std::function<std::optional<remote::RemoteAbsolutePointer>(
14841537
remote::RemoteAddress)>;
@@ -1511,6 +1564,7 @@ class TypeRefBuilder {
15111564
ByteReader OpaqueByteReader;
15121565
StringReader OpaqueStringReader;
15131566
PointerReader OpaquePointerReader;
1567+
PointerSymbolResolver OpaquePointerSymbolResolver;
15141568
DynamicSymbolResolver OpaqueDynamicSymbolResolver;
15151569
IntVariableReader OpaqueIntVariableReader;
15161570

@@ -1549,6 +1603,11 @@ class TypeRefBuilder {
15491603
-> std::optional<remote::RemoteAbsolutePointer> {
15501604
return reader.Reader->readPointer(address, size);
15511605
}),
1606+
OpaquePointerSymbolResolver(
1607+
[&reader](remote::RemoteAddress address)
1608+
-> std::optional<remote::RemoteAbsolutePointer> {
1609+
return reader.Reader->resolvePointerAsSymbol(address);
1610+
}),
15521611
OpaqueDynamicSymbolResolver(
15531612
[&reader](remote::RemoteAddress address)
15541613
-> std::optional<remote::RemoteAbsolutePointer> {

include/swift/RemoteInspection/TypeRefs.def

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ TYPEREF(Tuple, TypeRef)
2323
TYPEREF(Function, TypeRef)
2424
TYPEREF(ProtocolComposition, TypeRef)
2525
TYPEREF(ConstrainedExistential, TypeRef)
26+
TYPEREF(SymbolicExtendedExistential, TypeRef)
2627
TYPEREF(Metatype, TypeRef)
2728
TYPEREF(ExistentialMetatype, TypeRef)
2829
TYPEREF(GenericTypeParameter, TypeRef)

lib/AST/ASTDemangler.cpp

Lines changed: 35 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -767,8 +767,12 @@ Type ASTBuilder::createExistentialMetatypeType(
767767
Type ASTBuilder::createConstrainedExistentialType(
768768
Type base, ArrayRef<BuiltRequirement> constraints,
769769
ArrayRef<BuiltInverseRequirement> inverseRequirements) {
770+
llvm::SmallDenseMap<Identifier, Type> primaryAssociatedTypeNames;
770771
llvm::SmallDenseMap<AssociatedTypeDecl *, Type> primaryAssociatedTypes;
771772
llvm::SmallDenseSet<AssociatedTypeDecl *> claimed;
773+
llvm::SmallDenseSet<Identifier> claimedNames;
774+
unsigned duplicates = 0;
775+
bool ambiguousName = false;
772776

773777
for (const auto &req : constraints) {
774778
switch (req.getKind()) {
@@ -782,7 +786,18 @@ Type ASTBuilder::createConstrainedExistentialType(
782786
if (auto *memberTy = req.getFirstType()->getAs<DependentMemberType>()) {
783787
if (memberTy->getBase()->is<GenericTypeParamType>()) {
784788
// This is the only case we understand so far.
785-
primaryAssociatedTypes[memberTy->getAssocType()] = req.getSecondType();
789+
if (auto *assocTy = memberTy->getAssocType())
790+
primaryAssociatedTypes[assocTy] = req.getSecondType();
791+
else {
792+
auto &ty = primaryAssociatedTypeNames[memberTy->getName()];
793+
if (!ty)
794+
ty = req.getSecondType();
795+
else if (ty.getPointer() == req.getSecondType().getPointer())
796+
++duplicates;
797+
else
798+
ambiguousName = true;
799+
}
800+
786801
continue;
787802
}
788803
}
@@ -799,11 +814,24 @@ Type ASTBuilder::createConstrainedExistentialType(
799814

800815
llvm::SmallVector<Type, 4> args;
801816
for (auto *assocTy : proto->getPrimaryAssociatedTypes()) {
802-
auto found = primaryAssociatedTypes.find(assocTy);
803-
if (found == primaryAssociatedTypes.end())
804-
return protoTy;
805-
args.push_back(found->second);
806-
claimed.insert(found->first);
817+
{
818+
auto found = primaryAssociatedTypes.find(assocTy);
819+
if (found != primaryAssociatedTypes.end()) {
820+
args.push_back(found->second);
821+
claimed.insert(found->first);
822+
continue;
823+
}
824+
}
825+
{
826+
if (ambiguousName)
827+
return protoTy;
828+
auto found = primaryAssociatedTypeNames.find(assocTy->getName());
829+
if (found != primaryAssociatedTypeNames.end()) {
830+
args.push_back(found->second);
831+
claimedNames.insert(found->first);
832+
continue;
833+
}
834+
}
807835
}
808836

809837
// We may not have any arguments because the constrained existential is a
@@ -839,6 +867,7 @@ Type ASTBuilder::createConstrainedExistentialType(
839867

840868
// Make sure that all arguments were actually used.
841869
ASSERT(claimed.size() == primaryAssociatedTypes.size());
870+
ASSERT(claimedNames.size() + duplicates == primaryAssociatedTypeNames.size());
842871

843872
// Handle inverse requirements.
844873
if (!inverseRequirements.empty()) {

stdlib/public/RemoteInspection/TypeLowering.cpp

Lines changed: 42 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1154,6 +1154,7 @@ class ExistentialTypeInfoBuilder {
11541154
TypeConverter &TC;
11551155
std::vector<const TypeRef *> Protocols;
11561156
const TypeRef *Superclass = nullptr;
1157+
remote::RemoteAbsolutePointer Shape;
11571158
ExistentialTypeRepresentation Representation;
11581159
ReferenceCounting Refcounting;
11591160
bool ObjC;
@@ -1258,6 +1259,10 @@ class ExistentialTypeInfoBuilder {
12581259
}
12591260
}
12601261

1262+
void examineShape() {
1263+
1264+
}
1265+
12611266
public:
12621267
ExistentialTypeInfoBuilder(TypeConverter &TC)
12631268
: TC(TC), Representation(ExistentialTypeRepresentation::Opaque),
@@ -1321,8 +1326,27 @@ class ExistentialTypeInfoBuilder {
13211326
Representation = ExistentialTypeRepresentation::Class;
13221327
}
13231328

1329+
void addShape(const ProtocolCompositionTypeRef *Protocol,
1330+
ExtendedExistentialTypeShapeFlags Flags) {
1331+
switch (Flags.getSpecialKind()) {
1332+
case ExtendedExistentialTypeShapeFlags::SpecialKind::Class:
1333+
Representation = ExistentialTypeRepresentation::Class;
1334+
break;
1335+
case ExtendedExistentialTypeShapeFlags::SpecialKind::Metatype:
1336+
case ExtendedExistentialTypeShapeFlags::SpecialKind::ExplicitLayout:
1337+
case ExtendedExistentialTypeShapeFlags::SpecialKind::None:
1338+
Representation = ExistentialTypeRepresentation::Opaque;
1339+
break;
1340+
}
1341+
1342+
if (Protocol)
1343+
for (auto *Protocol : Protocol->getProtocols())
1344+
addProtocol(Protocol);
1345+
}
1346+
13241347
const TypeInfo *build(remote::TypeInfoProvider *ExternalTypeInfo) {
13251348
examineProtocols();
1349+
examineShape();
13261350

13271351
if (Invalid)
13281352
return nullptr;
@@ -1780,6 +1804,11 @@ class HasFixedSize
17801804
return true;
17811805
}
17821806

1807+
bool visitSymbolicExtendedExistentialTypeRef(
1808+
const SymbolicExtendedExistentialTypeRef *SEET) {
1809+
return true;
1810+
}
1811+
17831812
bool
17841813
visitSILBoxTypeRef(const SILBoxTypeRef *SB) {
17851814
return true;
@@ -1923,6 +1952,11 @@ class HasSingletonMetatype
19231952
return MetatypeRepresentation::Thin;
19241953
}
19251954

1955+
MetatypeRepresentation visitSymbolicExtendedExistentialTypeRef(
1956+
const SymbolicExtendedExistentialTypeRef *SEET) {
1957+
return MetatypeRepresentation::Thin;
1958+
}
1959+
19261960
MetatypeRepresentation visitMetatypeTypeRef(const MetatypeTypeRef *M) {
19271961
if (M->wasAbstract())
19281962
return MetatypeRepresentation::Thick;
@@ -2520,6 +2554,13 @@ class LowerType
25202554
return builder.buildMetatype(ExternalTypeInfo);
25212555
}
25222556

2557+
const TypeInfo *visitSymbolicExtendedExistentialTypeRef(
2558+
const SymbolicExtendedExistentialTypeRef *SEET) {
2559+
ExistentialTypeInfoBuilder builder(TC);
2560+
builder.addShape(SEET->getProtocol(), SEET->getFlags());
2561+
return builder.build(ExternalTypeInfo);
2562+
}
2563+
25232564
const TypeInfo *
25242565
visitGenericTypeParameterTypeRef(const GenericTypeParameterTypeRef *GTP) {
25252566
DEBUG_LOG(fprintf(stderr, "Unresolved generic TypeRef: "); GTP->dump());
@@ -2736,7 +2777,7 @@ const RecordTypeInfo *TypeConverter::getClassInstanceTypeInfo(
27362777
swift_unreachable("Unhandled FieldDescriptorKind in switch.");
27372778
}
27382779

2739-
} // namespace reflection
2780+
} // namespace reflection
27402781
} // namespace swift
27412782

27422783
#endif

0 commit comments

Comments
 (0)