Skip to content

Commit 054bb2c

Browse files
committed
swift-reflection-dump support for unresolved opaque return types.
Resolve mangled names containing symbolic references to indirect opaque type descriptors from other dylibs by demangling the referenced symbol name, like we do for other kinds of context descriptor. Add an OpaqueArchetypeTypeRef that can represent unresolved opaque types in the Reflection library.
1 parent 9053413 commit 054bb2c

File tree

7 files changed

+186
-5
lines changed

7 files changed

+186
-5
lines changed

include/swift/Reflection/TypeRef.h

Lines changed: 80 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -316,7 +316,8 @@ class TupleTypeRef final : public TypeRef {
316316

317317
public:
318318
TupleTypeRef(std::vector<const TypeRef *> Elements, bool Variadic=false)
319-
: TypeRef(TypeRefKind::Tuple), Elements(Elements), Variadic(Variadic) {}
319+
: TypeRef(TypeRefKind::Tuple), Elements(std::move(Elements)),
320+
Variadic(Variadic) {}
320321

321322
template <typename Allocator>
322323
static const TupleTypeRef *create(Allocator &A,
@@ -338,6 +339,84 @@ class TupleTypeRef final : public TypeRef {
338339
}
339340
};
340341

342+
class OpaqueArchetypeTypeRef final : public TypeRef {
343+
std::string ID;
344+
std::string Description;
345+
unsigned Ordinal;
346+
// Each ArrayRef in ArgumentLists references into the buffer owned by this
347+
// vector, which must not be modified after construction.
348+
std::vector<const TypeRef *> AllArgumentsBuf;
349+
std::vector<ArrayRef<const TypeRef *>> ArgumentLists;
350+
351+
static TypeRefID Profile(StringRef idString,
352+
StringRef description, unsigned ordinal,
353+
ArrayRef<ArrayRef<const TypeRef *>> argumentLists) {
354+
TypeRefID ID;
355+
ID.addString(idString);
356+
ID.addInteger(ordinal);
357+
for (auto argList : argumentLists) {
358+
ID.addInteger(0u);
359+
for (auto arg : argList)
360+
ID.addPointer(arg);
361+
}
362+
363+
return ID;
364+
}
365+
366+
public:
367+
OpaqueArchetypeTypeRef(StringRef id,
368+
StringRef description, unsigned ordinal,
369+
ArrayRef<ArrayRef<const TypeRef *>> argumentLists)
370+
: TypeRef(TypeRefKind::OpaqueArchetype),
371+
ID(id), Description(description), Ordinal(ordinal)
372+
{
373+
std::vector<unsigned> argumentListLengths;
374+
375+
for (auto argList : argumentLists) {
376+
argumentListLengths.push_back(argList.size());
377+
AllArgumentsBuf.insert(AllArgumentsBuf.end(),
378+
argList.begin(), argList.end());
379+
}
380+
auto *data = AllArgumentsBuf.data();
381+
for (auto length : argumentListLengths) {
382+
ArgumentLists.push_back(ArrayRef<const TypeRef *>(data, length));
383+
data += length;
384+
}
385+
assert(data == AllArgumentsBuf.data() + AllArgumentsBuf.size());
386+
}
387+
388+
template <typename Allocator>
389+
static const OpaqueArchetypeTypeRef *create(Allocator &A,
390+
StringRef id, StringRef description,
391+
unsigned ordinal,
392+
ArrayRef<ArrayRef<const TypeRef *>> arguments) {
393+
FIND_OR_CREATE_TYPEREF(A, OpaqueArchetypeTypeRef,
394+
id, description, ordinal, arguments);
395+
}
396+
397+
ArrayRef<ArrayRef<const TypeRef *>> getArgumentLists() const {
398+
return ArgumentLists;
399+
}
400+
401+
unsigned getOrdinal() const {
402+
return Ordinal;
403+
}
404+
405+
/// A stable identifier for the opaque type.
406+
StringRef getID() const {
407+
return ID;
408+
}
409+
410+
/// A human-digestible, but not necessarily stable, description of the opaque type.
411+
StringRef getDescription() const {
412+
return Description;
413+
}
414+
415+
static bool classof(const TypeRef *T) {
416+
return T->getKind() == TypeRefKind::OpaqueArchetype;
417+
}
418+
};
419+
341420
class FunctionTypeRef final : public TypeRef {
342421
using Param = remote::FunctionParam<const TypeRef *>;
343422

include/swift/Reflection/TypeRefBuilder.h

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -372,6 +372,7 @@ class TypeRefBuilder {
372372
unsigned ordinal) {
373373
// TODO: Produce a type ref for the opaque type if the underlying type isn't
374374
// available.
375+
opaqueDescriptor->dump();
375376

376377
// Try to resolve to the underlying type, if we can.
377378
if (opaqueDescriptor->getKind() ==
@@ -392,7 +393,15 @@ class TypeRefBuilder {
392393

393394
return underlyingTy->subst(*this, subs);
394395
}
395-
return nullptr;
396+
397+
// Otherwise, build a type ref that represents the opaque type.
398+
return OpaqueArchetypeTypeRef::create(*this,
399+
mangleNode(opaqueDescriptor,
400+
SymbolicResolver(),
401+
Dem),
402+
nodeToString(opaqueDescriptor),
403+
ordinal,
404+
genericArgs);
396405
}
397406

398407
const TupleTypeRef *

include/swift/Reflection/TypeRefs.def

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ TYPEREF(ForeignClass, TypeRef)
3030
TYPEREF(ObjCClass, TypeRef)
3131
TYPEREF(ObjCProtocol, TypeRef)
3232
TYPEREF(Opaque, TypeRef)
33+
TYPEREF(OpaqueArchetype, TypeRef)
3334
#define REF_STORAGE(Name, ...) \
3435
TYPEREF(Name##Storage, TypeRef)
3536
#include "swift/AST/ReferenceStorage.def"

include/swift/Remote/MetadataReader.h

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1077,11 +1077,16 @@ class MetadataReader {
10771077
demangledSymbol = demangledSymbol->getChild(0);
10781078
assert(demangledSymbol->getKind() == Demangle::Node::Kind::Type);
10791079
break;
1080-
// We don't handle pointers to other symbols yet.
1081-
// TODO: Opaque type descriptors could be useful.
1080+
// Pointers to opaque type descriptors demangle to the name of the opaque
1081+
// type declaration.
1082+
case Demangle::Node::Kind::OpaqueTypeDescriptor:
1083+
demangledSymbol = demangledSymbol->getChild(0);
1084+
break;
1085+
// We don't handle pointers to other symbols yet.
10821086
default:
10831087
return nullptr;
10841088
}
1089+
10851090
return demangledSymbol;
10861091
}
10871092

lib/Demangling/Demangler.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -716,8 +716,10 @@ NodePointer Demangler::demangleSymbolicReference(unsigned char rawKind,
716716
return nullptr;
717717

718718
// Types register as substitutions even when symbolically referenced.
719+
// OOPS: Except for opaque type references!
719720
if (kind == SymbolicReferenceKind::Context &&
720-
resolved->getKind() != Node::Kind::OpaqueTypeDescriptorSymbolicReference)
721+
resolved->getKind() != Node::Kind::OpaqueTypeDescriptorSymbolicReference &&
722+
resolved->getKind() != Node::Kind::OpaqueReturnTypeOf)
721723
addSubstitution(resolved);
722724
return resolved;
723725
}

stdlib/public/Reflection/TypeLowering.cpp

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1584,6 +1584,10 @@ class HasFixedSize
15841584
bool visitOpaqueTypeRef(const OpaqueTypeRef *O) {
15851585
return false;
15861586
}
1587+
1588+
bool visitOpaqueArchetypeTypeRef(const OpaqueArchetypeTypeRef *O) {
1589+
return false;
1590+
}
15871591
};
15881592

15891593
bool TypeConverter::hasFixedSize(const TypeRef *TR) {
@@ -1705,6 +1709,10 @@ class HasSingletonMetatype
17051709
MetatypeRepresentation visitOpaqueTypeRef(const OpaqueTypeRef *O) {
17061710
return MetatypeRepresentation::Unknown;
17071711
}
1712+
1713+
MetatypeRepresentation visitOpaqueArchetypeTypeRef(const OpaqueArchetypeTypeRef *O) {
1714+
return MetatypeRepresentation::Unknown;
1715+
}
17081716
};
17091717

17101718
class EnumTypeInfoBuilder {
@@ -2153,6 +2161,13 @@ class LowerType
21532161
DEBUG_LOG(fprintf(stderr, "Can't lower opaque TypeRef"));
21542162
return nullptr;
21552163
}
2164+
2165+
const TypeInfo *visitOpaqueArchetypeTypeRef(const OpaqueArchetypeTypeRef *O) {
2166+
// TODO: Provide a hook for the client to try to resolve the opaque archetype
2167+
// with additional information?
2168+
DEBUG_LOG(fprintf(stderr, "Can't lower unresolved opaque archetype TypeRef"));
2169+
return nullptr;
2170+
}
21562171
};
21572172

21582173
const TypeInfo *TypeConverter::getTypeInfo(const TypeRef *TR) {

stdlib/public/Reflection/TypeRef.cpp

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -256,6 +256,22 @@ class PrintTypeRef : public TypeRefVisitor<PrintTypeRef, void> {
256256
fprintf(file, ")");
257257
}
258258

259+
void visitOpaqueArchetypeTypeRef(const OpaqueArchetypeTypeRef *O) {
260+
printHeader("opaque_archetype");
261+
printField("id", O->getID());
262+
printField("description", O->getDescription());
263+
fprintf(file, " ordinal %u ", O->getOrdinal());
264+
for (auto argList : O->getArgumentLists()) {
265+
fprintf(file, "\n");
266+
fprintf(indent(Indent + 2), "args: <");
267+
for (auto arg : argList) {
268+
printRec(arg);
269+
}
270+
fprintf(file, ">");
271+
}
272+
fprintf(file, ")");
273+
}
274+
259275
void visitOpaqueTypeRef(const OpaqueTypeRef *O) {
260276
printHeader("opaque");
261277
fprintf(file, ")");
@@ -348,6 +364,10 @@ struct TypeRefIsConcrete
348364
bool visitOpaqueTypeRef(const OpaqueTypeRef *O) {
349365
return true;
350366
}
367+
368+
bool visitOpaqueArchetypeTypeRef(const OpaqueArchetypeTypeRef *O) {
369+
return false;
370+
}
351371

352372
#define REF_STORAGE(Name, name, ...) \
353373
bool visit##Name##StorageTypeRef(const Name##StorageTypeRef *US) { \
@@ -660,6 +680,36 @@ class DemanglingForTypeRef
660680
Demangle::NodePointer visitOpaqueTypeRef(const OpaqueTypeRef *O) {
661681
return Dem.createNode(Node::Kind::OpaqueType);
662682
}
683+
684+
Demangle::NodePointer visitOpaqueArchetypeTypeRef(const OpaqueArchetypeTypeRef *O) {
685+
auto decl = Dem.demangleSymbol(O->getID());
686+
if (!decl)
687+
return nullptr;
688+
689+
auto index = Dem.createNode(Node::Kind::Index, O->getOrdinal());
690+
691+
auto argNodeLists = Dem.createNode(Node::Kind::TypeList);
692+
for (auto argList : O->getArgumentLists()) {
693+
auto argNodeList = Dem.createNode(Node::Kind::TypeList);
694+
695+
for (auto arg : argList) {
696+
auto argNode = visit(arg);
697+
if (!argNode)
698+
return nullptr;
699+
700+
argNodeList->addChild(argNode, Dem);
701+
}
702+
703+
argNodeLists->addChild(argNodeList, Dem);
704+
}
705+
706+
auto node = Dem.createNode(Node::Kind::OpaqueType);
707+
node->addChild(decl, Dem);
708+
node->addChild(index, Dem);
709+
node->addChild(argNodeLists, Dem);
710+
711+
return node;
712+
}
663713
};
664714

665715
Demangle::NodePointer TypeRef::getDemangling(Demangle::Demangler &Dem) const {
@@ -831,6 +881,11 @@ class ThickenMetatype
831881
const TypeRef *visitOpaqueTypeRef(const OpaqueTypeRef *O) {
832882
return O;
833883
}
884+
885+
const TypeRef *visitOpaqueArchetypeTypeRef(const OpaqueArchetypeTypeRef *O) {
886+
return O;
887+
}
888+
834889
};
835890

836891
static const TypeRef *
@@ -1009,6 +1064,21 @@ class TypeRefSubstitution
10091064
const TypeRef *visitOpaqueTypeRef(const OpaqueTypeRef *O) {
10101065
return O;
10111066
}
1067+
1068+
const TypeRef *visitOpaqueArchetypeTypeRef(const OpaqueArchetypeTypeRef *O) {
1069+
std::vector<const TypeRef *> newArgsBuffer;
1070+
for (auto argList : O->getArgumentLists()) {
1071+
for (auto arg : argList) {
1072+
newArgsBuffer.push_back(visit(arg));
1073+
}
1074+
}
1075+
1076+
std::vector<ArrayRef<const TypeRef *>> newArgLists;
1077+
1078+
return OpaqueArchetypeTypeRef::create(Builder, O->getID(), O->getDescription(),
1079+
O->getOrdinal(),
1080+
newArgLists);
1081+
}
10121082
};
10131083

10141084
const TypeRef *

0 commit comments

Comments
 (0)