Skip to content

Fix symbolic references #16086

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Apr 21, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions include/swift/Demangling/Demangle.h
Original file line number Diff line number Diff line change
Expand Up @@ -466,6 +466,14 @@ void mangleIdentifier(const char *data, size_t length,
/// This should always round-trip perfectly with demangleSymbolAsNode.
std::string mangleNode(const NodePointer &root);

using SymbolicResolver = llvm::function_ref<Demangle::NodePointer (const void *)>;

/// \brief Remangle a demangled parse tree, using a callback to resolve
/// symbolic references.
///
/// This should always round-trip perfectly with demangleSymbolAsNode.
std::string mangleNode(const NodePointer &root, SymbolicResolver resolver);

/// Remangle in the old mangling scheme.
///
/// This is only used for objc-runtime names and should be removed as soon as
Expand Down
19 changes: 15 additions & 4 deletions lib/Demangling/Remangler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,9 @@ class Remangler {
// nested generics. This factory owns them.
NodeFactory Factory;

// A callback for resolving symbolic references.
SymbolicResolver Resolver;

StringRef getBufferStr() const { return Buffer.getStringRef(); }

void resetBuffer(size_t toPos) { Buffer.resetSize(toPos); }
Expand Down Expand Up @@ -284,7 +287,8 @@ class Remangler {
#include "swift/Demangling/DemangleNodes.def"

public:
Remangler(DemanglerPrinter &Buffer) : Buffer(Buffer) {}
Remangler(DemanglerPrinter &Buffer,
SymbolicResolver Resolver) : Buffer(Buffer), Resolver(Resolver) {}

void mangle(Node *node) {
switch (node->getKind()) {
Expand Down Expand Up @@ -1994,18 +1998,25 @@ void Remangler::mangleUnresolvedSymbolicReference(Node *node) {
}

void Remangler::mangleSymbolicReference(Node *node) {
unreachable("should not try to mangle a symbolic reference; "
"resolve it to a non-symbolic demangling tree instead");
return mangle(Resolver((const void *)node->getIndex()));
}

} // anonymous namespace

/// The top-level interface to the remangler.
std::string Demangle::mangleNode(const NodePointer &node) {
return mangleNode(node, [](const void *) -> NodePointer {
unreachable("should not try to mangle a symbolic reference; "
"resolve it to a non-symbolic demangling tree instead");
});
}

std::string
Demangle::mangleNode(const NodePointer &node, SymbolicResolver resolver) {
if (!node) return "";

DemanglerPrinter printer;
Remangler(printer).mangle(node);
Remangler(printer, resolver).mangle(node);

return std::move(printer).str();
}
Expand Down
13 changes: 10 additions & 3 deletions stdlib/public/runtime/MetadataLookup.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -263,7 +263,8 @@ _searchTypeMetadataRecords(const TypeMetadataPrivateState &T,
}

static const TypeContextDescriptor *
_findNominalTypeDescriptor(Demangle::NodePointer node) {
_findNominalTypeDescriptor(Demangle::NodePointer node,
Demangle::Demangler &Dem) {
const TypeContextDescriptor *foundNominal = nullptr;
auto &T = TypeMetadataRecords.get();

Expand All @@ -275,7 +276,13 @@ _findNominalTypeDescriptor(Demangle::NodePointer node) {
return cast<TypeContextDescriptor>(
(const ContextDescriptor *)symbolicNode->getIndex());

auto mangledName = Demangle::mangleNode(node);
auto mangledName =
Demangle::mangleNode(node,
[&](const void *context) -> NodePointer {
return _buildDemanglingForContext(
(const ContextDescriptor *) context,
{}, false, Dem);
});

// Look for an existing entry.
// Find the bucket for the metadata entry.
Expand Down Expand Up @@ -696,7 +703,7 @@ class DecodedMetadataBuilder {
#endif

// Look for a nominal type descriptor based on its mangled name.
return _findNominalTypeDescriptor(node);
return _findNominalTypeDescriptor(node, demangler);
}

BuiltProtocolDecl createProtocolDecl(
Expand Down
7 changes: 7 additions & 0 deletions test/stdlib/Inputs/Mirror/MirrorOther.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
struct OtherStruct {
let a: OtherOuter.Inner
let b: OtherOuterGeneric<Int>.Inner<String>
}

struct OtherOuter {}
struct OtherOuterGeneric<T> {}
Loading