Skip to content

Commit 3d7017a

Browse files
authored
Merge pull request #3064 from slavapestov/nested-generic-types
2 parents b2240d0 + cdc0b77 commit 3d7017a

File tree

15 files changed

+600
-120
lines changed

15 files changed

+600
-120
lines changed

include/swift/AST/Mangle.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,7 @@ class Mangler {
9292
void mangleClosureEntity(const AbstractClosureExpr *closure,
9393
unsigned uncurryingLevel);
9494
void mangleNominalType(const NominalTypeDecl *decl);
95+
void mangleBoundGenericType(Type type);
9596
void mangleProtocolDecl(const ProtocolDecl *protocol);
9697
void mangleType(Type type, unsigned uncurryingLevel);
9798
void mangleDirectness(bool isIndirect);

lib/AST/Mangle.cpp

Lines changed: 46 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -940,32 +940,17 @@ void Mangler::mangleType(Type type, unsigned uncurryLevel) {
940940
Buffer << '_';
941941
return;
942942

943-
case TypeKind::UnboundGeneric: {
944-
// We normally reject unbound types in IR-generation, but there
945-
// are several occasions in which we'd like to mangle them in the
946-
// abstract.
947-
auto decl = cast<UnboundGenericType>(tybase)->getDecl();
948-
mangleNominalType(cast<NominalTypeDecl>(decl));
949-
return;
950-
}
951-
943+
case TypeKind::UnboundGeneric:
952944
case TypeKind::Class:
953945
case TypeKind::Enum:
954-
case TypeKind::Struct: {
955-
return mangleNominalType(cast<NominalType>(tybase)->getDecl());
956-
}
957-
946+
case TypeKind::Struct:
958947
case TypeKind::BoundGenericClass:
959948
case TypeKind::BoundGenericEnum:
960949
case TypeKind::BoundGenericStruct: {
961-
// type ::= 'G' <type> <type>+ '_'
962-
auto *boundType = cast<BoundGenericType>(tybase);
963-
Buffer << 'G';
964-
mangleNominalType(boundType->getDecl());
965-
for (auto arg : boundType->getGenericArgs()) {
966-
mangleType(arg, /*uncurry*/ 0);
967-
}
968-
Buffer << '_';
950+
if (type->isSpecialized())
951+
mangleBoundGenericType(type);
952+
else
953+
mangleNominalType(tybase->getAnyNominal());
969954
return;
970955
}
971956

@@ -1332,6 +1317,46 @@ void Mangler::mangleNominalType(const NominalTypeDecl *decl) {
13321317
addSubstitution(key);
13331318
}
13341319

1320+
static void
1321+
collectBoundGenericArgs(Type type,
1322+
SmallVectorImpl<SmallVector<Type, 2>> &genericArgs) {
1323+
if (auto *unboundType = type->getAs<UnboundGenericType>()) {
1324+
if (auto parent = unboundType->getParent())
1325+
collectBoundGenericArgs(parent, genericArgs);
1326+
genericArgs.push_back({});
1327+
} else if (auto *nominalType = type->getAs<NominalType>()) {
1328+
if (auto parent = nominalType->getParent())
1329+
collectBoundGenericArgs(parent, genericArgs);
1330+
genericArgs.push_back({});
1331+
} else {
1332+
auto *boundType = type->castTo<BoundGenericType>();
1333+
if (auto parent = boundType->getParent())
1334+
collectBoundGenericArgs(parent, genericArgs);
1335+
1336+
SmallVector<Type, 2> args;
1337+
for (auto arg : boundType->getGenericArgs())
1338+
args.push_back(arg);
1339+
genericArgs.push_back(args);
1340+
}
1341+
}
1342+
1343+
void Mangler::mangleBoundGenericType(Type type) {
1344+
// type ::= 'G' <type> (<type>+ '_')+
1345+
Buffer << 'G';
1346+
auto *nominal = type->getAnyNominal();
1347+
mangleNominalType(nominal);
1348+
1349+
SmallVector<SmallVector<Type, 2>, 2> genericArgs;
1350+
collectBoundGenericArgs(type, genericArgs);
1351+
assert(!genericArgs.empty());
1352+
1353+
for (auto args : genericArgs) {
1354+
for (auto arg : args)
1355+
mangleType(arg, /*uncurry*/ 0);
1356+
Buffer << '_';
1357+
}
1358+
}
1359+
13351360
void Mangler::mangleProtocolDecl(const ProtocolDecl *protocol) {
13361361
Buffer << 'P';
13371362
mangleContextOf(protocol);

lib/Basic/Demangle.cpp

Lines changed: 72 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1154,6 +1154,73 @@ class Demangler {
11541154
return nullptr;
11551155
}
11561156

1157+
NodePointer demangleBoundGenericArgs(NodePointer nominalType) {
1158+
// Generic arguments for the outermost type come first.
1159+
NodePointer parentOrModule = nominalType->getChild(0);
1160+
if (parentOrModule->getKind() != Node::Kind::Module) {
1161+
parentOrModule = demangleBoundGenericArgs(parentOrModule);
1162+
1163+
// Rebuild this type with the new parent type, which may have
1164+
// had its generic arguments applied.
1165+
NodePointer result = NodeFactory::create(nominalType->getKind());
1166+
result->addChild(parentOrModule);
1167+
result->addChild(nominalType->getChild(1));
1168+
1169+
nominalType = result;
1170+
}
1171+
1172+
NodePointer args = NodeFactory::create(Node::Kind::TypeList);
1173+
while (!Mangled.nextIf('_')) {
1174+
NodePointer type = demangleType();
1175+
if (!type)
1176+
return nullptr;
1177+
args->addChild(type);
1178+
if (Mangled.isEmpty())
1179+
return nullptr;
1180+
}
1181+
1182+
// If there were no arguments at this level there is nothing left
1183+
// to do.
1184+
if (args->getNumChildren() == 0)
1185+
return nominalType;
1186+
1187+
// Otherwise, build a bound generic type node from the unbound
1188+
// type and arguments.
1189+
NodePointer unboundType = NodeFactory::create(Node::Kind::Type);
1190+
unboundType->addChild(nominalType);
1191+
1192+
Node::Kind kind;
1193+
switch (nominalType->getKind()) { // look through Type node
1194+
case Node::Kind::Class:
1195+
kind = Node::Kind::BoundGenericClass;
1196+
break;
1197+
case Node::Kind::Structure:
1198+
kind = Node::Kind::BoundGenericStructure;
1199+
break;
1200+
case Node::Kind::Enum:
1201+
kind = Node::Kind::BoundGenericEnum;
1202+
break;
1203+
default:
1204+
return nullptr;
1205+
}
1206+
NodePointer result = NodeFactory::create(kind);
1207+
result->addChild(unboundType);
1208+
result->addChild(args);
1209+
return result;
1210+
}
1211+
1212+
NodePointer demangleBoundGenericType() {
1213+
// bound-generic-type ::= 'G' nominal-type (args+ '_')+
1214+
//
1215+
// Each level of nominal type nesting has its own list of arguments.
1216+
1217+
NodePointer nominalType = demangleNominalType();
1218+
if (!nominalType)
1219+
return nullptr;
1220+
1221+
return demangleBoundGenericArgs(nominalType);
1222+
}
1223+
11571224
NodePointer demangleContext() {
11581225
// context ::= module
11591226
// context ::= entity
@@ -1191,6 +1258,8 @@ class Demangler {
11911258
return demangleSubstitutionIndex();
11921259
if (Mangled.nextIf('s'))
11931260
return NodeFactory::create(Node::Kind::Module, STDLIB_NAME);
1261+
if (Mangled.nextIf('G'))
1262+
return demangleBoundGenericType();
11941263
if (isStartOfEntity(Mangled.peek()))
11951264
return demangleEntity();
11961265
return demangleModule();
@@ -1872,37 +1941,7 @@ class Demangler {
18721941
return demangleFunctionType(Node::Kind::UncurriedFunctionType);
18731942
}
18741943
if (c == 'G') {
1875-
NodePointer unboundType = demangleType();
1876-
if (!unboundType)
1877-
return nullptr;
1878-
NodePointer type_list = NodeFactory::create(Node::Kind::TypeList);
1879-
while (!Mangled.nextIf('_')) {
1880-
NodePointer type = demangleType();
1881-
if (!type)
1882-
return nullptr;
1883-
type_list->addChild(type);
1884-
if (Mangled.isEmpty())
1885-
return nullptr;
1886-
}
1887-
Node::Kind bound_type_kind;
1888-
switch (unboundType->getChild(0)->getKind()) { // look through Type node
1889-
case Node::Kind::Class:
1890-
bound_type_kind = Node::Kind::BoundGenericClass;
1891-
break;
1892-
case Node::Kind::Structure:
1893-
bound_type_kind = Node::Kind::BoundGenericStructure;
1894-
break;
1895-
case Node::Kind::Enum:
1896-
bound_type_kind = Node::Kind::BoundGenericEnum;
1897-
break;
1898-
default:
1899-
return nullptr;
1900-
}
1901-
NodePointer type_application =
1902-
NodeFactory::create(bound_type_kind);
1903-
type_application->addChild(unboundType);
1904-
type_application->addChild(type_list);
1905-
return type_application;
1944+
return demangleBoundGenericType();
19061945
}
19071946
if (c == 'X') {
19081947
if (Mangled.nextIf('b')) {
@@ -2049,10 +2088,8 @@ class Demangler {
20492088

20502089
return nullptr;
20512090
}
2052-
if (isStartOfNominalType(c)) {
2053-
NodePointer nominal_type = demangleDeclarationName(nominalTypeMarkerToNodeKind(c));
2054-
return nominal_type;
2055-
}
2091+
if (isStartOfNominalType(c))
2092+
return demangleDeclarationName(nominalTypeMarkerToNodeKind(c));
20562093
return nullptr;
20572094
}
20582095

0 commit comments

Comments
 (0)