Skip to content

Commit 0f5233d

Browse files
committed
ASTDemangler: Implement extension lookup
1 parent 55605ce commit 0f5233d

File tree

3 files changed

+125
-2
lines changed

3 files changed

+125
-2
lines changed

include/swift/AST/ASTDemangler.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,9 @@ class ASTBuilder {
114114

115115
private:
116116
bool validateNominalParent(NominalTypeDecl *decl, Type parent);
117+
CanGenericSignature demangleGenericSignature(
118+
NominalTypeDecl *nominalDecl,
119+
const Demangle::NodePointer &node);
117120
DeclContext *findDeclContext(const Demangle::NodePointer &node);
118121
ModuleDecl *findModule(const Demangle::NodePointer &node);
119122
Demangle::NodePointer findModuleNode(const Demangle::NodePointer &node);

lib/AST/ASTDemangler.cpp

Lines changed: 90 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
#include "swift/AST/ASTContext.h"
2525
#include "swift/AST/Decl.h"
2626
#include "swift/AST/GenericSignature.h"
27+
#include "swift/AST/GenericSignatureBuilder.h"
2728
#include "swift/AST/Module.h"
2829
#include "swift/AST/NameLookup.h"
2930
#include "swift/AST/Type.h"
@@ -424,6 +425,55 @@ ASTBuilder::getForeignModuleKind(const Demangle::NodePointer &node) {
424425
.Default(None);
425426
}
426427

428+
CanGenericSignature ASTBuilder::demangleGenericSignature(
429+
NominalTypeDecl *nominalDecl,
430+
const Demangle::NodePointer &node) {
431+
GenericSignatureBuilder builder(Ctx);
432+
builder.addGenericSignature(nominalDecl->getGenericSignature());
433+
434+
for (auto &child : *node) {
435+
if (child->getKind() ==
436+
Demangle::Node::Kind::DependentGenericParamCount)
437+
continue;
438+
439+
if (child->getNumChildren() != 2)
440+
return CanGenericSignature();
441+
auto subjectType = swift::Demangle::decodeMangledType(
442+
*this, child->getChild(0));
443+
auto constraintType = swift::Demangle::decodeMangledType(
444+
*this, child->getChild(1));
445+
if (!subjectType || !constraintType)
446+
return CanGenericSignature();
447+
448+
auto source =
449+
GenericSignatureBuilder::FloatingRequirementSource::forAbstract();
450+
451+
switch (child->getKind()) {
452+
case Demangle::Node::Kind::DependentGenericConformanceRequirement: {
453+
builder.addRequirement(
454+
Requirement(constraintType->isExistentialType()
455+
? RequirementKind::Conformance
456+
: RequirementKind::Superclass,
457+
subjectType, constraintType),
458+
source, nullptr);
459+
break;
460+
}
461+
case Demangle::Node::Kind::DependentGenericSameTypeRequirement: {
462+
builder.addRequirement(
463+
Requirement(RequirementKind::SameType,
464+
subjectType, constraintType),
465+
source, nullptr);
466+
break;
467+
}
468+
default:
469+
return CanGenericSignature();
470+
}
471+
}
472+
473+
return std::move(builder).computeGenericSignature(SourceLoc())
474+
->getCanonicalSignature();
475+
}
476+
427477
DeclContext *
428478
ASTBuilder::findDeclContext(const Demangle::NodePointer &node) {
429479
switch (node->getKind()) {
@@ -500,9 +550,41 @@ ASTBuilder::findDeclContext(const Demangle::NodePointer &node) {
500550
case Demangle::Node::Kind::Global:
501551
return findDeclContext(node->getChild(0));
502552

553+
case Demangle::Node::Kind::Extension: {
554+
auto *moduleDecl = dyn_cast_or_null<ModuleDecl>(
555+
findDeclContext(node->getChild(0)));
556+
if (!moduleDecl)
557+
return nullptr;
558+
559+
auto *nominalDecl = dyn_cast_or_null<NominalTypeDecl>(
560+
findDeclContext(node->getChild(1)));
561+
if (!nominalDecl)
562+
return nullptr;
563+
564+
CanGenericSignature genericSig;
565+
if (node->getNumChildren() > 2)
566+
genericSig = demangleGenericSignature(nominalDecl, node->getChild(2));
567+
568+
for (auto *ext : nominalDecl->getExtensions()) {
569+
if (ext->getParentModule() != moduleDecl)
570+
continue;
571+
572+
if (!ext->isConstrainedExtension()) {
573+
if (!genericSig)
574+
return ext;
575+
continue;
576+
}
577+
578+
if (ext->getGenericSignature()->getCanonicalSignature()
579+
== genericSig) {
580+
return ext;
581+
}
582+
}
583+
584+
return nullptr;
585+
}
586+
503587
// Bail out on other kinds of contexts.
504-
// TODO: extensions
505-
// TODO: local contexts
506588
default:
507589
return nullptr;
508590
}
@@ -515,6 +597,12 @@ ASTBuilder::findNominalTypeDecl(DeclContext *dc,
515597
Demangle::Node::Kind kind) {
516598
auto module = dc->getParentModule();
517599

600+
// When looking into an extension, look into the nominal instead; the
601+
// important thing is that the module, obtained above, is the module
602+
// containing the extension and not the module containing the nominal
603+
if (isa<ExtensionDecl>(dc))
604+
dc = dc->getSelfNominalTypeDecl();
605+
518606
SmallVector<ValueDecl *, 4> lookupResults;
519607
module->lookupMember(lookupResults, dc, name, privateDiscriminator);
520608

test/TypeDecoder/extensions.swift

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
// RUN: %empty-directory(%t)
2+
3+
// RUN: %target-build-swift -emit-executable %s -g -o %t/extensions -emit-module
4+
// RUN: sed -ne '/\/\/ *DEMANGLE: /s/\/\/ *DEMANGLE: *//p' < %s > %t/input
5+
// RUN: %lldb-moduleimport-test %t/extensions -type-from-mangled=%t/input | %FileCheck %s
6+
7+
struct Concrete {}
8+
9+
extension Concrete {
10+
struct Nested {}
11+
}
12+
13+
struct Generic<T> {}
14+
15+
protocol Proto {}
16+
17+
extension Generic where T : Proto {
18+
struct Nested1 {}
19+
}
20+
21+
extension Generic where T == Int {
22+
struct Nested2 {}
23+
}
24+
25+
// DEMANGLE: $s10extensions8ConcreteV6NestedVD
26+
// CHECK: Concrete.Nested
27+
28+
// DEMANGLE: $s10extensions7GenericVA2A5ProtoRzlE7Nested1Vyx_GD
29+
// CHECK: Generic<τ_0_0>.Nested1
30+
31+
// DEMANGLE: $s10extensions7GenericVAASiRszlE7Nested2VySi_GD
32+
// CHECK: Generic<Int>.Nested2

0 commit comments

Comments
 (0)