Skip to content

Commit 9e7826b

Browse files
committed
[Remote AST] Resolve local types using anonymous context descriptor mangling.
When the mangled name is available within an anonymous context descriptor for a local type, use that mangled name to help RemoteAST resolve lookups based on local type metadata.
1 parent 9bf4043 commit 9e7826b

File tree

2 files changed

+54
-20
lines changed

2 files changed

+54
-20
lines changed

include/swift/Remote/MetadataReader.h

Lines changed: 43 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1423,13 +1423,38 @@ class MetadataReader {
14231423
return name;
14241424
}
14251425

1426+
/// Read and demangle the name of an anonymous context.
1427+
Demangle::NodePointer demangleAnonymousContextName(
1428+
ContextDescriptorRef contextRef,
1429+
Demangler &dem) {
1430+
auto anonymousBuffer = cast<TargetAnonymousContextDescriptor<Runtime>>(
1431+
contextRef.getLocalBuffer());
1432+
1433+
if (!anonymousBuffer->hasMangledName())
1434+
return nullptr;
1435+
1436+
// Read the mangled name.
1437+
auto mangledContextName = anonymousBuffer->getMangledContextName();
1438+
auto mangledNameAddress = resolveRelativeField(contextRef,
1439+
mangledContextName->name);
1440+
1441+
std::string mangledName;
1442+
if (!Reader->readString(RemoteAddress(mangledNameAddress), mangledName))
1443+
return nullptr;
1444+
1445+
return dem.demangleSymbol(mangledName);
1446+
}
1447+
14261448
/// If we have a context whose parent context is an anonymous context
14271449
/// that provides the local/private name for the current context,
14281450
/// produce a mangled node describing the name of \c context.
14291451
Demangle::NodePointer
14301452
adoptAnonymousContextName(ContextDescriptorRef contextRef,
14311453
Optional<ContextDescriptorRef> &parentContextRef,
1432-
Demangler &dem) {
1454+
Demangler &dem,
1455+
Demangle::NodePointer &outerNode) {
1456+
outerNode = nullptr;
1457+
14331458
if (!parentContextRef || !*parentContextRef)
14341459
return nullptr;
14351460

@@ -1444,21 +1469,7 @@ class MetadataReader {
14441469
if (!anonymousParent)
14451470
return nullptr;
14461471

1447-
// Only perform this transformation when we have a mangled name describing
1448-
// the context.
1449-
if (!anonymousParent->hasMangledName())
1450-
return nullptr;
1451-
1452-
// Read the mangled name.
1453-
auto mangledContextName = anonymousParent->getMangledContextName();
1454-
auto mangledNameAddress = resolveRelativeField(*parentContextRef,
1455-
mangledContextName->name);
1456-
1457-
std::string mangledName;
1458-
if (!Reader->readString(RemoteAddress(mangledNameAddress), mangledName))
1459-
return nullptr;
1460-
1461-
auto mangledNode = dem.demangleSymbol(mangledName);
1472+
auto mangledNode = demangleAnonymousContextName(*parentContextRef, dem);
14621473
if (!mangledNode)
14631474
return nullptr;
14641475

@@ -1469,9 +1480,9 @@ class MetadataReader {
14691480
return nullptr;
14701481

14711482
// Dig out the name of the entity.
1472-
// FIXME: LocalDeclName
14731483
NodePointer nameChild = mangledNode->getChild(1);
1474-
if (nameChild->getKind() != Node::Kind::PrivateDeclName ||
1484+
if ((nameChild->getKind() != Node::Kind::PrivateDeclName &&
1485+
nameChild->getKind() != Node::Kind::LocalDeclName) ||
14751486
nameChild->getNumChildren() < 2)
14761487
return nullptr;
14771488

@@ -1497,6 +1508,9 @@ class MetadataReader {
14971508
// context entirely.
14981509
parentContextRef = readParentContextDescriptor(*parentContextRef);
14991510

1511+
// The outer node is the first child.
1512+
outerNode = mangledNode->getChild(0);
1513+
15001514
// Return the name.
15011515
return nameChild;
15021516
}
@@ -1509,8 +1523,9 @@ class MetadataReader {
15091523

15101524
// If the parent is an anonymous context that provides a complete
15111525
// name for this node, note that.
1526+
NodePointer demangledParentNode = nullptr;
15121527
auto nameNode = adoptAnonymousContextName(
1513-
descriptor, parentDescriptorResult, dem);
1528+
descriptor, parentDescriptorResult, dem, demangledParentNode);
15141529

15151530
// If there was a problem reading the parent descriptor, we're done.
15161531
if (!parentDescriptorResult) return nullptr;
@@ -1520,10 +1535,18 @@ class MetadataReader {
15201535
if (auto parentDescriptor = *parentDescriptorResult) {
15211536
parentDemangling =
15221537
buildContextDescriptorMangling(parentDescriptor, dem);
1523-
if (!parentDemangling)
1538+
if (!parentDemangling && !demangledParentNode)
15241539
return nullptr;
15251540
}
15261541

1542+
// If we have a better parent node produced from an enclosing nominal
1543+
// context, use that.
1544+
if (demangledParentNode &&
1545+
(!parentDemangling ||
1546+
parentDemangling->getKind() == Node::Kind::AnonymousContext)) {
1547+
parentDemangling = demangledParentNode;
1548+
}
1549+
15271550
Demangle::Node::Kind nodeKind;
15281551
Optional<TypeImportInfo<std::string>> importInfo;
15291552

test/RemoteAST/nominal_types.swift

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,3 +126,14 @@ struct M<T, U> {
126126
}
127127
}
128128
M<Int, String>.testPrivate()
129+
130+
struct N {
131+
static func testPrivate() {
132+
struct LocalStruct {
133+
struct Inner { }
134+
}
135+
// CHECK: LocalStruct.Inner
136+
printType(LocalStruct.Inner.self)
137+
}
138+
}
139+
N.testPrivate()

0 commit comments

Comments
 (0)