Skip to content

Commit b695193

Browse files
committed
ASTDemangler: Implement type alias types
Debug info uses a special mangling where type aliases can be represented without being desugared; attempt to reconstruct the TypeAliasType in this case.
1 parent d80cace commit b695193

File tree

11 files changed

+501
-133
lines changed

11 files changed

+501
-133
lines changed

include/swift/AST/ASTDemangler.h

Lines changed: 20 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ class ASTBuilder {
4747

4848
public:
4949
using BuiltType = swift::Type;
50-
using BuiltNominalTypeDecl = swift::NominalTypeDecl *;
50+
using BuiltTypeDecl = swift::GenericTypeDecl *; // nominal or type alias
5151
using BuiltProtocolDecl = swift::ProtocolDecl *;
5252
explicit ASTBuilder(ASTContext &ctx) : Ctx(ctx) {}
5353

@@ -58,19 +58,22 @@ class ASTBuilder {
5858

5959
Type createBuiltinType(StringRef builtinName, StringRef mangledName);
6060

61-
NominalTypeDecl *createNominalTypeDecl(StringRef mangledName);
61+
GenericTypeDecl *createTypeDecl(StringRef mangledName, bool &typeAlias);
6262

63-
NominalTypeDecl *createNominalTypeDecl(const Demangle::NodePointer &node);
63+
GenericTypeDecl *createTypeDecl(const Demangle::NodePointer &node,
64+
bool &typeAlias);
6465

6566
ProtocolDecl *createProtocolDecl(const Demangle::NodePointer &node);
6667

67-
Type createNominalType(NominalTypeDecl *decl);
68+
Type createNominalType(GenericTypeDecl *decl);
6869

69-
Type createNominalType(NominalTypeDecl *decl, Type parent);
70+
Type createNominalType(GenericTypeDecl *decl, Type parent);
7071

71-
Type createBoundGenericType(NominalTypeDecl *decl, ArrayRef<Type> args);
72+
Type createTypeAliasType(GenericTypeDecl *decl, Type parent);
7273

73-
Type createBoundGenericType(NominalTypeDecl *decl, ArrayRef<Type> args,
74+
Type createBoundGenericType(GenericTypeDecl *decl, ArrayRef<Type> args);
75+
76+
Type createBoundGenericType(GenericTypeDecl *decl, ArrayRef<Type> args,
7477
Type parent);
7578

7679
Type createTupleType(ArrayRef<Type> eltTypes, StringRef labels,
@@ -113,7 +116,7 @@ class ASTBuilder {
113116
Type getOpaqueType();
114117

115118
private:
116-
bool validateNominalParent(NominalTypeDecl *decl, Type parent);
119+
bool validateParentType(TypeDecl *decl, Type parent);
117120
CanGenericSignature demangleGenericSignature(
118121
NominalTypeDecl *nominalDecl,
119122
const Demangle::NodePointer &node);
@@ -129,17 +132,17 @@ class ASTBuilder {
129132
Optional<ForeignModuleKind>
130133
getForeignModuleKind(const Demangle::NodePointer &node);
131134

132-
NominalTypeDecl *findNominalTypeDecl(DeclContext *dc,
133-
Identifier name,
134-
Identifier privateDiscriminator,
135+
GenericTypeDecl *findTypeDecl(DeclContext *dc,
136+
Identifier name,
137+
Identifier privateDiscriminator,
138+
Demangle::Node::Kind kind);
139+
GenericTypeDecl *findForeignTypeDecl(StringRef name,
140+
StringRef relatedEntityKind,
141+
ForeignModuleKind lookupKind,
135142
Demangle::Node::Kind kind);
136-
NominalTypeDecl *findForeignNominalTypeDecl(StringRef name,
137-
StringRef relatedEntityKind,
138-
ForeignModuleKind lookupKind,
139-
Demangle::Node::Kind kind);
140143

141-
static NominalTypeDecl *getAcceptableNominalTypeCandidate(ValueDecl *decl,
142-
Demangle::Node::Kind kind);
144+
static GenericTypeDecl *getAcceptableTypeDeclCandidate(ValueDecl *decl,
145+
Demangle::Node::Kind kind);
143146
};
144147

145148
} // namespace Demangle

include/swift/Demangling/TypeDecoder.h

Lines changed: 58 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,7 @@ static inline Optional<StringRef> getObjCClassOrProtocolName(
109109
template <typename BuilderType>
110110
class TypeDecoder {
111111
using BuiltType = typename BuilderType::BuiltType;
112-
using BuiltNominalTypeDecl = typename BuilderType::BuiltNominalTypeDecl;
112+
using BuiltTypeDecl = typename BuilderType::BuiltTypeDecl;
113113
using BuiltProtocolDecl = typename BuilderType::BuiltProtocolDecl;
114114
using NodeKind = Demangle::Node::Kind;
115115

@@ -150,14 +150,18 @@ class TypeDecoder {
150150
}
151151
case NodeKind::Enum:
152152
case NodeKind::Structure:
153-
case NodeKind::TypeAlias: // This can show up for imported Clang decls.
153+
case NodeKind::TypeAlias:
154154
case NodeKind::TypeSymbolicReference:
155155
{
156-
BuiltNominalTypeDecl typeDecl = BuiltNominalTypeDecl();
156+
BuiltTypeDecl typeDecl = BuiltTypeDecl();
157157
BuiltType parent = BuiltType();
158-
if (!decodeMangledNominalType(Node, typeDecl, parent))
158+
bool typeAlias = false;
159+
if (!decodeMangledTypeDecl(Node, typeDecl, parent, typeAlias))
159160
return BuiltType();
160161

162+
if (typeAlias && Node->getKind() == NodeKind::TypeAlias)
163+
return Builder.createTypeAliasType(typeDecl, parent);
164+
161165
return Builder.createNominalType(typeDecl, parent);
162166
}
163167
case NodeKind::BoundGenericClass:
@@ -177,13 +181,16 @@ class TypeDecoder {
177181
}
178182
case NodeKind::BoundGenericEnum:
179183
case NodeKind::BoundGenericStructure:
184+
case NodeKind::BoundGenericTypeAlias:
180185
case NodeKind::BoundGenericOtherNominalType: {
181186
if (Node->getNumChildren() < 2)
182187
return BuiltType();
183188

184-
BuiltNominalTypeDecl typeDecl = BuiltNominalTypeDecl();
189+
BuiltTypeDecl typeDecl = BuiltTypeDecl();
185190
BuiltType parent = BuiltType();
186-
if (!decodeMangledNominalType(Node->getChild(0), typeDecl, parent))
191+
bool typeAlias = false;
192+
if (!decodeMangledTypeDecl(Node->getChild(0), typeDecl,
193+
parent, typeAlias))
187194
return BuiltType();
188195

189196
std::vector<BuiltType> args;
@@ -200,6 +207,40 @@ class TypeDecoder {
200207

201208
return Builder.createBoundGenericType(typeDecl, args, parent);
202209
}
210+
case NodeKind::BoundGenericProtocol: {
211+
// This is a special case. When you write a protocol typealias with a
212+
// concrete type base, for example:
213+
//
214+
// protocol P { typealias A<T> = ... }
215+
// struct S : P {}
216+
// let x: S.A<Int> = ...
217+
//
218+
// The mangling tree looks like this:
219+
//
220+
// BoundGenericProtocol ---> BoundGenericTypeAlias
221+
// | |
222+
// | |
223+
// --> Protocol: P --> TypeAlias: A
224+
// | |
225+
// --> TypeList: --> TypeList:
226+
// | |
227+
// --> Structure: S --> Structure: Int
228+
//
229+
// When resolving the mangling tree to a decl, we strip off the
230+
// BoundGenericProtocol's *argument*, leaving behind only the
231+
// protocol reference.
232+
//
233+
// But when resolving it to a type, we want to *keep* the argument
234+
// so that the parent type becomes 'S' and not 'P'.
235+
if (Node->getNumChildren() < 2)
236+
return BuiltType();
237+
238+
const auto &genericArgs = Node->getChild(1);
239+
if (genericArgs->getNumChildren() != 1)
240+
return BuiltType();
241+
242+
return decodeMangledType(genericArgs->getChild(0));
243+
}
203244
case NodeKind::BuiltinTypeName: {
204245
auto mangledName = Demangle::mangleNode(Node);
205246
return Builder.createBuiltinType(Node->getText(), mangledName);
@@ -533,16 +574,18 @@ class TypeDecoder {
533574
}
534575

535576
private:
536-
bool decodeMangledNominalType(Demangle::NodePointer node,
537-
BuiltNominalTypeDecl &typeDecl,
538-
BuiltType &parent) {
577+
bool decodeMangledTypeDecl(Demangle::NodePointer node,
578+
BuiltTypeDecl &typeDecl,
579+
BuiltType &parent,
580+
bool &typeAlias) {
539581
if (node->getKind() == NodeKind::Type)
540-
return decodeMangledNominalType(node->getChild(0), typeDecl, parent);
582+
return decodeMangledTypeDecl(node->getChild(0), typeDecl,
583+
parent, typeAlias);
541584

542-
Demangle::NodePointer nominalNode;
585+
Demangle::NodePointer declNode;
543586
if (node->getKind() == NodeKind::TypeSymbolicReference) {
544587
// A symbolic reference can be directly resolved to a nominal type.
545-
nominalNode = node;
588+
declNode = node;
546589
} else {
547590
if (node->getNumChildren() < 2)
548591
return false;
@@ -554,7 +597,7 @@ class TypeDecoder {
554597
// in addition to a reference to the parent type. The
555598
// mangled name already includes the module and parent
556599
// types, if any.
557-
nominalNode = node;
600+
declNode = node;
558601
switch (parentContext->getKind()) {
559602
case Node::Kind::Module:
560603
break;
@@ -568,12 +611,12 @@ class TypeDecoder {
568611
parent = decodeMangledType(parentContext);
569612
// Remove any generic arguments from the context node, producing a
570613
// node that references the nominal type declaration.
571-
nominalNode =
614+
declNode =
572615
stripGenericArgsFromContextNode(node, Builder.getNodeFactory());
573616
break;
574617
}
575618
}
576-
typeDecl = Builder.createNominalTypeDecl(nominalNode);
619+
typeDecl = Builder.createTypeDecl(declNode, typeAlias);
577620
if (!typeDecl) return false;
578621

579622
return true;

include/swift/Reflection/TypeRefBuilder.h

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -159,7 +159,7 @@ class TypeRefBuilder {
159159

160160
public:
161161
using BuiltType = const TypeRef *;
162-
using BuiltNominalTypeDecl = Optional<std::string>;
162+
using BuiltTypeDecl = Optional<std::string>;
163163
using BuiltProtocolDecl = Optional<std::pair<std::string, bool /*isObjC*/>>;
164164

165165
TypeRefBuilder();
@@ -211,7 +211,7 @@ class TypeRefBuilder {
211211
}
212212

213213
Optional<std::string>
214-
createNominalTypeDecl(const Demangle::NodePointer &node) {
214+
createTypeDecl(const Demangle::NodePointer &node, bool &typeAlias) {
215215
return Demangle::mangleNode(node);
216216
}
217217

@@ -225,7 +225,8 @@ class TypeRefBuilder {
225225
return std::make_pair(name, true);
226226
}
227227

228-
Optional<std::string> createNominalTypeDecl(std::string &&mangledName) {
228+
Optional<std::string> createTypeDecl(std::string &&mangledName,
229+
bool &typeAlias) {
229230
return std::move(mangledName);
230231
}
231232

@@ -240,6 +241,13 @@ class TypeRefBuilder {
240241
return NominalTypeRef::create(*this, *mangledName, parent);
241242
}
242243

244+
const TypeRef *createTypeAliasType(
245+
const Optional<std::string> &mangledName,
246+
const TypeRef *parent) {
247+
// TypeRefs don't contain sugared types
248+
return nullptr;
249+
}
250+
243251
const BoundGenericTypeRef *
244252
createBoundGenericType(const Optional<std::string> &mangledName,
245253
const std::vector<const TypeRef *> &args) {

include/swift/Remote/MetadataReader.h

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ template <typename Runtime, typename BuilderType>
9898
class MetadataReader {
9999
public:
100100
using BuiltType = typename BuilderType::BuiltType;
101-
using BuiltNominalTypeDecl = typename BuilderType::BuiltNominalTypeDecl;
101+
using BuiltTypeDecl = typename BuilderType::BuiltTypeDecl;
102102
using BuiltProtocolDecl = typename BuilderType::BuiltProtocolDecl;
103103
using StoredPointer = typename Runtime::StoredPointer;
104104
using StoredSize = typename Runtime::StoredSize;
@@ -869,10 +869,10 @@ class MetadataReader {
869869

870870
/// Given the address of a nominal type descriptor, attempt to resolve
871871
/// its nominal type declaration.
872-
BuiltNominalTypeDecl readNominalTypeFromDescriptor(StoredPointer address) {
872+
BuiltTypeDecl readNominalTypeFromDescriptor(StoredPointer address) {
873873
auto descriptor = readContextDescriptor(address);
874874
if (!descriptor)
875-
return BuiltNominalTypeDecl();
875+
return BuiltTypeDecl();
876876

877877
return buildNominalTypeDecl(descriptor);
878878
}
@@ -1685,14 +1685,15 @@ class MetadataReader {
16851685

16861686
/// Given a read nominal type descriptor, attempt to build a
16871687
/// nominal type decl from it.
1688-
BuiltNominalTypeDecl
1688+
BuiltTypeDecl
16891689
buildNominalTypeDecl(ContextDescriptorRef descriptor) {
16901690
// Build the demangling tree from the context tree.
16911691
Demangler dem;
16921692
auto node = buildContextMangling(descriptor, dem);
16931693
if (!node || node->getKind() != Node::Kind::Type)
1694-
return BuiltNominalTypeDecl();
1695-
BuiltNominalTypeDecl decl = Builder.createNominalTypeDecl(node);
1694+
return BuiltTypeDecl();
1695+
bool typeAlias = false;
1696+
BuiltTypeDecl decl = Builder.createTypeDecl(node, typeAlias);
16961697
return decl;
16971698
}
16981699

@@ -1803,7 +1804,7 @@ class MetadataReader {
18031804
return BuiltType();
18041805

18051806
// From that, attempt to resolve a nominal type.
1806-
BuiltNominalTypeDecl typeDecl = buildNominalTypeDecl(descriptor);
1807+
BuiltTypeDecl typeDecl = buildNominalTypeDecl(descriptor);
18071808
if (!typeDecl)
18081809
return BuiltType();
18091810

0 commit comments

Comments
 (0)