Skip to content

Commit 3430cb9

Browse files
authored
Merge pull request swiftlang#22144 from DougGregor/remote-ast-local-types
[Remote AST] Resolve local types using anonymous context descriptor mangling.
2 parents 2be98a2 + 9e7826b commit 3430cb9

File tree

4 files changed

+73
-20
lines changed

4 files changed

+73
-20
lines changed

include/swift/AST/Module.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1052,6 +1052,8 @@ class SourceFile final : public FileUnit {
10521052
virtual void
10531053
getPrecedenceGroups(SmallVectorImpl<PrecedenceGroupDecl*> &results) const override;
10541054

1055+
virtual TypeDecl *lookupLocalType(llvm::StringRef MangledName) const override;
1056+
10551057
virtual void
10561058
getLocalTypeDecls(SmallVectorImpl<TypeDecl*> &results) const override;
10571059

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

lib/AST/Module.cpp

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
#include "swift/AST/PrettyStackTrace.h"
3333
#include "swift/AST/PrintOptions.h"
3434
#include "swift/AST/ProtocolConformance.h"
35+
#include "swift/AST/TypeCheckRequests.h"
3536
#include "swift/Basic/Compiler.h"
3637
#include "swift/Basic/SourceManager.h"
3738
#include "swift/Basic/Statistic.h"
@@ -565,6 +566,22 @@ void SourceFile::getLocalTypeDecls(SmallVectorImpl<TypeDecl*> &Results) const {
565566
Results.append(LocalTypeDecls.begin(), LocalTypeDecls.end());
566567
}
567568

569+
TypeDecl *SourceFile::lookupLocalType(llvm::StringRef mangledName) const {
570+
ASTContext &ctx = getASTContext();
571+
for (auto typeDecl : LocalTypeDecls) {
572+
auto typeMangledName = evaluateOrDefault(ctx.evaluator,
573+
USRGenerationRequest { typeDecl },
574+
std::string());
575+
if (typeMangledName.find("s:") == 0)
576+
typeMangledName = typeMangledName.substr(2);
577+
578+
if (mangledName == typeMangledName)
579+
return typeDecl;
580+
}
581+
582+
return nullptr;
583+
}
584+
568585
void ModuleDecl::getDisplayDecls(SmallVectorImpl<Decl*> &Results) const {
569586
// FIXME: Should this do extra access control filtering?
570587
FORWARD(getDisplayDecls, (Results));

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)