Skip to content

Commit 2be98a2

Browse files
authored
Merge pull request swiftlang#22078 from slavapestov/type-reconstruction-rewrite
ASTDemangler improvements
2 parents 72f0efe + b695193 commit 2be98a2

32 files changed

+1546
-270
lines changed

include/swift/AST/ASTDemangler.h

Lines changed: 28 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,6 @@
2525
#include "llvm/ADT/ArrayRef.h"
2626
#include "llvm/ADT/StringRef.h"
2727
#include "swift/AST/Types.h"
28-
#include "swift/AST/TypeRepr.h"
2928
#include "swift/Demangling/Demangler.h"
3029
#include "swift/Demangling/TypeDecoder.h"
3130

@@ -48,7 +47,7 @@ class ASTBuilder {
4847

4948
public:
5049
using BuiltType = swift::Type;
51-
using BuiltNominalTypeDecl = swift::NominalTypeDecl *;
50+
using BuiltTypeDecl = swift::GenericTypeDecl *; // nominal or type alias
5251
using BuiltProtocolDecl = swift::ProtocolDecl *;
5352
explicit ASTBuilder(ASTContext &ctx) : Ctx(ctx) {}
5453

@@ -57,21 +56,24 @@ class ASTBuilder {
5756

5857
Demangle::NodeFactory &getNodeFactory() { return Factory; }
5958

60-
Type createBuiltinType(const std::string &mangledName);
59+
Type createBuiltinType(StringRef builtinName, StringRef mangledName);
6160

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

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

6666
ProtocolDecl *createProtocolDecl(const Demangle::NodePointer &node);
6767

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

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

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

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

7779
Type createTupleType(ArrayRef<Type> eltTypes, StringRef labels,
@@ -90,6 +92,8 @@ class ASTBuilder {
9092

9193
Type createGenericTypeParameterType(unsigned depth, unsigned index);
9294

95+
Type createDependentMemberType(StringRef member, Type base);
96+
9397
Type createDependentMemberType(StringRef member, Type base,
9498
ProtocolDecl *protocol);
9599

@@ -103,14 +107,19 @@ class ASTBuilder {
103107

104108
ProtocolDecl *createObjCProtocolDecl(StringRef name);
105109

110+
Type createDynamicSelfType(Type selfType);
111+
106112
Type createForeignClassType(StringRef mangledName);
107113

108114
Type getUnnamedForeignClassType();
109115

110116
Type getOpaqueType();
111117

112118
private:
113-
bool validateNominalParent(NominalTypeDecl *decl, Type parent);
119+
bool validateParentType(TypeDecl *decl, Type parent);
120+
CanGenericSignature demangleGenericSignature(
121+
NominalTypeDecl *nominalDecl,
122+
const Demangle::NodePointer &node);
114123
DeclContext *findDeclContext(const Demangle::NodePointer &node);
115124
ModuleDecl *findModule(const Demangle::NodePointer &node);
116125
Demangle::NodePointer findModuleNode(const Demangle::NodePointer &node);
@@ -123,39 +132,17 @@ class ASTBuilder {
123132
Optional<ForeignModuleKind>
124133
getForeignModuleKind(const Demangle::NodePointer &node);
125134

126-
NominalTypeDecl *findNominalTypeDecl(DeclContext *dc,
127-
Identifier name,
128-
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,
129142
Demangle::Node::Kind kind);
130-
NominalTypeDecl *findForeignNominalTypeDecl(StringRef name,
131-
StringRef relatedEntityKind,
132-
ForeignModuleKind lookupKind,
133-
Demangle::Node::Kind kind);
134-
135-
Type checkTypeRepr(TypeRepr *repr);
136-
137-
static NominalTypeDecl *getAcceptableNominalTypeCandidate(ValueDecl *decl,
138-
Demangle::Node::Kind kind);
139143

140-
class TypeReprList {
141-
SmallVector<FixedTypeRepr, 4> Reprs;
142-
SmallVector<TypeRepr*, 4> Refs;
143-
144-
public:
145-
explicit TypeReprList(ArrayRef<Type> types) {
146-
Reprs.reserve(types.size());
147-
Refs.reserve(types.size());
148-
149-
for (auto type : types) {
150-
Reprs.emplace_back(type, SourceLoc());
151-
Refs.push_back(&Reprs.back());
152-
}
153-
}
154-
155-
ArrayRef<TypeRepr*> getList() const {
156-
return Refs;
157-
}
158-
};
144+
static GenericTypeDecl *getAcceptableTypeDeclCandidate(ValueDecl *decl,
145+
Demangle::Node::Kind kind);
159146
};
160147

161148
} // namespace Demangle

include/swift/Demangling/TypeDecoder.h

Lines changed: 70 additions & 18 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,9 +207,43 @@ 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);
205-
return Builder.createBuiltinType(mangledName);
246+
return Builder.createBuiltinType(Node->getText(), mangledName);
206247
}
207248
case NodeKind::Metatype:
208249
case NodeKind::ExistentialMetatype: {
@@ -288,7 +329,16 @@ class TypeDecoder {
288329

289330
return BuiltType();
290331
}
332+
case NodeKind::DynamicSelf: {
333+
if (Node->getNumChildren() != 1)
334+
return BuiltType();
291335

336+
auto selfType = decodeMangledType(Node->getChild(0));
337+
if (!selfType)
338+
return BuiltType();
339+
340+
return Builder.createDynamicSelfType(selfType);
341+
}
292342
case NodeKind::DependentGenericParamType: {
293343
auto depth = Node->getChild(0)->getIndex();
294344
auto index = Node->getChild(1)->getIndex();
@@ -464,7 +514,7 @@ class TypeDecoder {
464514
auto member = Node->getChild(1)->getText();
465515
auto assocTypeChild = Node->getChild(1);
466516
if (assocTypeChild->getNumChildren() < 1)
467-
return BuiltType();
517+
return Builder.createDependentMemberType(member, base);
468518

469519
auto protocol = decodeMangledProtocolType(assocTypeChild->getChild(0));
470520
if (!protocol)
@@ -516,24 +566,26 @@ class TypeDecoder {
516566
case NodeKind::SILBoxTypeWithLayout: {
517567
// TODO: Implement SILBoxTypeRefs with layout. As a stopgap, specify the
518568
// NativeObject type ref.
519-
return Builder.createBuiltinType("Bo");
569+
return Builder.createBuiltinType("Builtin.NativeObject", "Bo");
520570
}
521571
default:
522572
return BuiltType();
523573
}
524574
}
525575

526576
private:
527-
bool decodeMangledNominalType(Demangle::NodePointer node,
528-
BuiltNominalTypeDecl &typeDecl,
529-
BuiltType &parent) {
577+
bool decodeMangledTypeDecl(Demangle::NodePointer node,
578+
BuiltTypeDecl &typeDecl,
579+
BuiltType &parent,
580+
bool &typeAlias) {
530581
if (node->getKind() == NodeKind::Type)
531-
return decodeMangledNominalType(node->getChild(0), typeDecl, parent);
582+
return decodeMangledTypeDecl(node->getChild(0), typeDecl,
583+
parent, typeAlias);
532584

533-
Demangle::NodePointer nominalNode;
585+
Demangle::NodePointer declNode;
534586
if (node->getKind() == NodeKind::TypeSymbolicReference) {
535587
// A symbolic reference can be directly resolved to a nominal type.
536-
nominalNode = node;
588+
declNode = node;
537589
} else {
538590
if (node->getNumChildren() < 2)
539591
return false;
@@ -545,7 +597,7 @@ class TypeDecoder {
545597
// in addition to a reference to the parent type. The
546598
// mangled name already includes the module and parent
547599
// types, if any.
548-
nominalNode = node;
600+
declNode = node;
549601
switch (parentContext->getKind()) {
550602
case Node::Kind::Module:
551603
break;
@@ -559,12 +611,12 @@ class TypeDecoder {
559611
parent = decodeMangledType(parentContext);
560612
// Remove any generic arguments from the context node, producing a
561613
// node that references the nominal type declaration.
562-
nominalNode =
614+
declNode =
563615
stripGenericArgsFromContextNode(node, Builder.getNodeFactory());
564616
break;
565617
}
566618
}
567-
typeDecl = Builder.createNominalTypeDecl(nominalNode);
619+
typeDecl = Builder.createTypeDecl(declNode, typeAlias);
568620
if (!typeDecl) return false;
569621

570622
return true;

include/swift/Reflection/TypeRefBuilder.h

Lines changed: 25 additions & 4 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();
@@ -205,12 +205,13 @@ class TypeRefBuilder {
205205
/// Factory methods for all TypeRef kinds
206206
///
207207

208-
const BuiltinTypeRef *createBuiltinType(const std::string &mangledName) {
208+
const BuiltinTypeRef *createBuiltinType(const std::string &builtinName,
209+
const std::string &mangledName) {
209210
return BuiltinTypeRef::create(*this, mangledName);
210211
}
211212

212213
Optional<std::string>
213-
createNominalTypeDecl(const Demangle::NodePointer &node) {
214+
createTypeDecl(const Demangle::NodePointer &node, bool &typeAlias) {
214215
return Demangle::mangleNode(node);
215216
}
216217

@@ -224,7 +225,8 @@ class TypeRefBuilder {
224225
return std::make_pair(name, true);
225226
}
226227

227-
Optional<std::string> createNominalTypeDecl(std::string &&mangledName) {
228+
Optional<std::string> createTypeDecl(std::string &&mangledName,
229+
bool &typeAlias) {
228230
return std::move(mangledName);
229231
}
230232

@@ -239,6 +241,13 @@ class TypeRefBuilder {
239241
return NominalTypeRef::create(*this, *mangledName, parent);
240242
}
241243

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+
242251
const BoundGenericTypeRef *
243252
createBoundGenericType(const Optional<std::string> &mangledName,
244253
const std::vector<const TypeRef *> &args) {
@@ -300,6 +309,13 @@ class TypeRefBuilder {
300309
return GenericTypeParameterTypeRef::create(*this, depth, index);
301310
}
302311

312+
const DependentMemberTypeRef *
313+
createDependentMemberType(const std::string &member,
314+
const TypeRef *base) {
315+
// Should not have unresolved dependent member types here.
316+
return nullptr;
317+
}
318+
303319
const DependentMemberTypeRef *
304320
createDependentMemberType(const std::string &member,
305321
const TypeRef *base,
@@ -321,6 +337,11 @@ class TypeRefBuilder {
321337
return SILBoxTypeRef::create(*this, base);
322338
}
323339

340+
const TypeRef *createDynamicSelfType(const TypeRef *selfType) {
341+
// TypeRefs should not contain DynamicSelfType.
342+
return nullptr;
343+
}
344+
324345
const ObjCClassTypeRef *getUnnamedObjCClassType() {
325346
return createObjCClassType("");
326347
}

0 commit comments

Comments
 (0)