Skip to content

Commit 2d84981

Browse files
committed
Improve the mangling of typealiases.
- Allow them to use substitutions. - Consistently use 'a' as a mangling operator. - For generic typealiases, include the alias as context for any generic parameters. Typealiases don't show up in symbol names, which always refer to canonical types, but they are mangled for debug info and for USRs (unique identifiers used by SourceKit), so it's good to get this right.
1 parent 5de0a39 commit 2d84981

File tree

16 files changed

+97
-102
lines changed

16 files changed

+97
-102
lines changed

docs/ABI.rst

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -889,7 +889,7 @@ Entities
889889
entity-spec ::= decl-name type 'i' // subscript ('i'ndex) itself (not the individual accessors)
890890
entity-spec ::= decl-name type 'v' // variable
891891
entity-spec ::= decl-name type 'f' ACCESSOR
892-
entity-spec ::= decl-name type 'fp' // generic type parameter (not used?)
892+
entity-spec ::= decl-name type 'fp' // generic type parameter
893893
entity-spec ::= decl-name type 'fo' // enum element (currently not used)
894894

895895
ACCESSOR ::= 'm' // materializeForSet
@@ -958,14 +958,15 @@ Types
958958

959959
::
960960

961-
nominal-type ::= substitution
962-
nominal-type ::= context decl-name 'C' // nominal class type
963-
nominal-type ::= context decl-name 'O' // nominal enum type
964-
nominal-type ::= context decl-name 'V' // nominal struct type
965-
nominal-type ::= protocol 'P' // nominal protocol type
961+
any-generic-type ::= substitution
962+
any-generic-type ::= context decl-name 'C' // nominal class type
963+
any-generic-type ::= context decl-name 'O' // nominal enum type
964+
any-generic-type ::= context decl-name 'V' // nominal struct type
965+
any-generic-type ::= protocol 'P' // nominal protocol type
966+
any-generic-type ::= context decl-name 'a' // typealias type (used in DWARF and USRs)
966967

967-
nominal-type ::= 'S' KNOWN-TYPE-KIND // known nominal type substitution
968-
nominal-type ::= 'S' NATURAL KNOWN-TYPE-KIND // repeated known type substitutions of the same kind
968+
any-generic-type ::= 'S' KNOWN-TYPE-KIND // known nominal type substitution
969+
any-generic-type ::= 'S' NATURAL KNOWN-TYPE-KIND // repeated known type substitutions of the same kind
969970

970971
KNOWN-TYPE-KIND ::= 'a' // Swift.Array
971972
KNOWN-TYPE-KIND ::= 'b' // Swift.Bool
@@ -995,7 +996,6 @@ Types
995996
type ::= 'Bp' // Builtin.RawPointer
996997
type ::= type 'Bv' NATURAL '_' // Builtin.Vec<n>x<type>
997998
type ::= 'Bw' // Builtin.Word
998-
type ::= context decl-name 'a' // Type alias (DWARF only)
999999
type ::= function-signature 'c' // function type
10001000
type ::= function-signature 'X' FUNCTION-KIND // special function type
10011001
type ::= bound-generic-type
@@ -1042,7 +1042,7 @@ Types
10421042

10431043
type ::= archetype
10441044
type ::= associated-type
1045-
type ::= nominal-type
1045+
type ::= any-generic-type
10461046
type ::= protocol-list 'p' // existential type
10471047
type ::= protocol-list superclass 'Xc' // existential type with superclass
10481048
type ::= protocol-list 'Xl' // existential type with AnyObject

include/swift/AST/ASTMangler.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -172,7 +172,7 @@ class ASTMangler : public Mangler {
172172

173173
void appendProtocolName(const ProtocolDecl *protocol);
174174

175-
void appendNominalType(const NominalTypeDecl *decl);
175+
void appendAnyGenericType(const GenericTypeDecl *decl);
176176

177177
void appendFunctionType(AnyFunctionType *fn, bool forceSingleParam);
178178

@@ -212,7 +212,7 @@ class ASTMangler : public Mangler {
212212

213213
void appendDeclType(const ValueDecl *decl, bool isFunctionMangling = false);
214214

215-
bool tryAppendStandardSubstitution(const NominalTypeDecl *type);
215+
bool tryAppendStandardSubstitution(const GenericTypeDecl *type);
216216

217217
void appendConstructorEntity(const ConstructorDecl *ctor, bool isAllocating);
218218

include/swift/Demangling/DemangleNodes.def

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -149,7 +149,7 @@ NODE(Tuple)
149149
NODE(TupleElement)
150150
NODE(TupleElementName)
151151
NODE(Type)
152-
NODE(TypeAlias)
152+
CONTEXT_NODE(TypeAlias)
153153
NODE(TypeList)
154154
NODE(TypeMangling)
155155
NODE(TypeMetadata)

include/swift/Demangling/Demangler.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -405,8 +405,7 @@ class Demangler : public NodeFactory {
405405
NodePointer popTypeAndGetChild();
406406
NodePointer popTypeAndGetNominal();
407407
NodePointer demangleBuiltinType();
408-
NodePointer demangleNominalType(Node::Kind kind);
409-
NodePointer demangleTypeAlias();
408+
NodePointer demangleAnyGenericType(Node::Kind kind);
410409
NodePointer demangleExtensionContext();
411410
NodePointer demanglePlainFunction();
412411
NodePointer popFunctionType(Node::Kind kind);

lib/AST/ASTMangler.cpp

Lines changed: 44 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -127,7 +127,7 @@ std::string ASTMangler::mangleInitializerEntity(const VarDecl *var,
127127

128128
std::string ASTMangler::mangleNominalType(const NominalTypeDecl *decl) {
129129
beginMangling();
130-
appendNominalType(decl);
130+
appendAnyGenericType(decl);
131131
return finalize();
132132
}
133133

@@ -322,7 +322,7 @@ std::string ASTMangler::mangleObjCRuntimeName(const NominalTypeDecl *Nominal) {
322322
}
323323
// For all other cases, we can use the new mangling.
324324
beginMangling();
325-
appendNominalType(Nominal);
325+
appendAnyGenericType(Nominal);
326326
return finalize();
327327
}
328328

@@ -342,9 +342,9 @@ std::string ASTMangler::mangleDeclAsUSR(const ValueDecl *Decl,
342342
appendConstructorEntity(Ctor, /*isAllocating=*/false);
343343
} else if (auto Dtor = dyn_cast<DestructorDecl>(Decl)) {
344344
appendDestructorEntity(Dtor, /*isDeallocating=*/false);
345-
} else if (auto NTD = dyn_cast<NominalTypeDecl>(Decl)) {
346-
appendNominalType(NTD);
347-
} else if (isa<TypeAliasDecl>(Decl) || isa<AssociatedTypeDecl>(Decl)) {
345+
} else if (auto GTD = dyn_cast<GenericTypeDecl>(Decl)) {
346+
appendAnyGenericType(GTD);
347+
} else if (isa<AssociatedTypeDecl>(Decl)) {
348348
appendContextOf(Decl);
349349
appendDeclName(Decl);
350350
} else {
@@ -510,7 +510,7 @@ static const char *getMetatypeRepresentationOp(MetatypeRepresentation Rep) {
510510
llvm_unreachable("Unhandled MetatypeRepresentation in switch.");
511511
}
512512

513-
static bool isStdlibType(const NominalTypeDecl *decl) {
513+
static bool isStdlibType(const TypeDecl *decl) {
514514
DeclContext *dc = decl->getDeclContext();
515515
return dc->isModuleScopeContext() && dc->getParentModule()->isStdlibModule();
516516
}
@@ -580,9 +580,7 @@ void ASTMangler::appendType(Type type) {
580580

581581
// For the DWARF output we want to mangle the type alias + context,
582582
// unless the type alias references a builtin type.
583-
appendContextOf(decl);
584-
appendDeclName(decl);
585-
return appendOperator("a");
583+
return appendAnyGenericType(decl);
586584
}
587585

588586
case TypeKind::Paren:
@@ -693,15 +691,15 @@ void ASTMangler::appendType(Type type) {
693691
appendType(GenArgs[0]);
694692
appendOperator("Sg");
695693
} else {
696-
appendNominalType(NDecl);
694+
appendAnyGenericType(NDecl);
697695
bool isFirstArgList = true;
698696
appendBoundGenericArgs(type, isFirstArgList);
699697
appendOperator("G");
700698
}
701699
addSubstitution(type.getPointer());
702700
return;
703701
}
704-
appendNominalType(tybase->getAnyNominal());
702+
appendAnyGenericType(tybase->getAnyNominal());
705703
return;
706704

707705
case TypeKind::SILFunction:
@@ -1143,10 +1141,7 @@ void ASTMangler::appendContext(const DeclContext *ctx) {
11431141
}
11441142

11451143
case DeclContextKind::GenericTypeDecl:
1146-
if (auto nomctx = dyn_cast<NominalTypeDecl>(ctx))
1147-
appendNominalType(nomctx);
1148-
else
1149-
appendContext(ctx->getParent());
1144+
appendAnyGenericType(cast<GenericTypeDecl>(ctx));
11501145
return;
11511146

11521147
case DeclContextKind::ExtensionDecl: {
@@ -1173,15 +1168,15 @@ void ASTMangler::appendContext(const DeclContext *ctx) {
11731168
auto sig = ExtD->getGenericSignature();
11741169
// If the extension is constrained, mangle the generic signature that
11751170
// constrains it.
1176-
appendNominalType(decl);
1171+
appendAnyGenericType(decl);
11771172
appendModule(ExtD->getParentModule());
11781173
if (sig && ExtD->isConstrainedExtension()) {
11791174
Mod = ExtD->getModuleContext();
11801175
appendGenericSignature(sig);
11811176
}
11821177
return appendOperator("E");
11831178
}
1184-
return appendNominalType(decl);
1179+
return appendAnyGenericType(decl);
11851180
}
11861181

11871182
case DeclContextKind::AbstractClosureExpr:
@@ -1258,42 +1253,50 @@ void ASTMangler::appendProtocolName(const ProtocolDecl *protocol) {
12581253
appendDeclName(protocol);
12591254
}
12601255

1261-
void ASTMangler::appendNominalType(const NominalTypeDecl *decl) {
1256+
void ASTMangler::appendAnyGenericType(const GenericTypeDecl *decl) {
12621257
// Check for certain standard types.
12631258
if (tryAppendStandardSubstitution(decl))
12641259
return;
12651260

12661261
// For generic types, this uses the unbound type.
1267-
TypeBase *key = decl->getDeclaredType().getPointer();
1262+
Type key;
1263+
if (auto *alias = dyn_cast<TypeAliasDecl>(decl)) {
1264+
if (alias->isGeneric())
1265+
key = alias->getUnboundGenericType();
1266+
else
1267+
key = alias->getDeclaredInterfaceType();
1268+
} else {
1269+
key = cast<NominalTypeDecl>(decl)->getDeclaredType();
1270+
}
12681271

12691272
// Try to mangle the entire name as a substitution.
1270-
if (tryMangleSubstitution(key))
1273+
if (tryMangleSubstitution(key.getPointer()))
12711274
return;
12721275

12731276
appendContextOf(decl);
12741277
appendDeclName(decl);
12751278

12761279
switch (decl->getKind()) {
1277-
#define NOMINAL_TYPE_DECL(id, parent)
1278-
#define DECL(id, parent) \
1279-
case DeclKind::id:
1280-
#include "swift/AST/DeclNodes.def"
1281-
llvm_unreachable("not a nominal type");
1282-
1283-
case DeclKind::Protocol:
1284-
appendOperator("P");
1285-
break;
1286-
case DeclKind::Class:
1287-
appendOperator("C");
1288-
break;
1289-
case DeclKind::Enum:
1290-
appendOperator("O");
1291-
break;
1292-
case DeclKind::Struct:
1293-
appendOperator("V");
1294-
break;
1280+
default:
1281+
llvm_unreachable("not a nominal type");
1282+
1283+
case DeclKind::TypeAlias:
1284+
appendOperator("a");
1285+
break;
1286+
case DeclKind::Protocol:
1287+
appendOperator("P");
1288+
break;
1289+
case DeclKind::Class:
1290+
appendOperator("C");
1291+
break;
1292+
case DeclKind::Enum:
1293+
appendOperator("O");
1294+
break;
1295+
case DeclKind::Struct:
1296+
appendOperator("V");
1297+
break;
12951298
}
1296-
addSubstitution(key);
1299+
addSubstitution(key.getPointer());
12971300
}
12981301

12991302
void ASTMangler::appendFunctionType(AnyFunctionType *fn,
@@ -1522,7 +1525,7 @@ void ASTMangler::appendAssociatedTypeName(DependentMemberType *dmt) {
15221525
appendIdentifier(assocTy->getName().str());
15231526
if (!OptimizeProtocolNames || !CurGenericSignature || !Mod
15241527
|| CurGenericSignature->getConformsTo(dmt->getBase(), *Mod).size() > 1) {
1525-
appendNominalType(assocTy->getProtocol());
1528+
appendAnyGenericType(assocTy->getProtocol());
15261529
}
15271530
}
15281531

@@ -1708,7 +1711,7 @@ void ASTMangler::appendDeclType(const ValueDecl *decl, bool isFunctionMangling)
17081711
}
17091712
}
17101713

1711-
bool ASTMangler::tryAppendStandardSubstitution(const NominalTypeDecl *decl) {
1714+
bool ASTMangler::tryAppendStandardSubstitution(const GenericTypeDecl *decl) {
17121715
// Bail out if our parent isn't the swift standard library.
17131716
if (!isStdlibType(decl))
17141717
return false;

lib/Demangling/Demangler.cpp

Lines changed: 6 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -362,7 +362,7 @@ NodePointer Demangler::demangleOperator() {
362362
switch (char c = nextChar()) {
363363
case 'A': return demangleMultiSubstitutions();
364364
case 'B': return demangleBuiltinType();
365-
case 'C': return demangleNominalType(Node::Kind::Class);
365+
case 'C': return demangleAnyGenericType(Node::Kind::Class);
366366
case 'D': return createWithChild(Node::Kind::TypeMangling,
367367
popNode(Node::Kind::Type));
368368
case 'E': return demangleExtensionContext();
@@ -374,17 +374,17 @@ NodePointer Demangler::demangleOperator() {
374374
case 'M': return demangleMetatype();
375375
case 'N': return createWithChild(Node::Kind::TypeMetadata,
376376
popNode(Node::Kind::Type));
377-
case 'O': return demangleNominalType(Node::Kind::Enum);
378-
case 'P': return demangleNominalType(Node::Kind::Protocol);
377+
case 'O': return demangleAnyGenericType(Node::Kind::Enum);
378+
case 'P': return demangleAnyGenericType(Node::Kind::Protocol);
379379
case 'Q': return demangleArchetype();
380380
case 'R': return demangleGenericRequirement();
381381
case 'S': return demangleStandardSubstitution();
382382
case 'T': return demangleThunkOrSpecialization();
383-
case 'V': return demangleNominalType(Node::Kind::Structure);
383+
case 'V': return demangleAnyGenericType(Node::Kind::Structure);
384384
case 'W': return demangleWitness();
385385
case 'X': return demangleSpecialType();
386386
case 'Z': return createWithChild(Node::Kind::Static, popNode(isEntity));
387-
case 'a': return demangleTypeAlias();
387+
case 'a': return demangleAnyGenericType(Node::Kind::TypeAlias);
388388
case 'c': return popFunctionType(Node::Kind::FunctionType);
389389
case 'd': return createNode(Node::Kind::VariadicMarker);
390390
case 'f': return demangleFunctionEntity();
@@ -759,20 +759,14 @@ NodePointer Demangler::demangleBuiltinType() {
759759
return createType(Ty);
760760
}
761761

762-
NodePointer Demangler::demangleNominalType(Node::Kind kind) {
762+
NodePointer Demangler::demangleAnyGenericType(Node::Kind kind) {
763763
NodePointer Name = popNode(isDeclName);
764764
NodePointer Ctx = popContext();
765765
NodePointer NTy = createType(createWithChildren(kind, Ctx, Name));
766766
addSubstitution(NTy);
767767
return NTy;
768768
}
769769

770-
NodePointer Demangler::demangleTypeAlias() {
771-
NodePointer Name = popNode(isDeclName);
772-
NodePointer Ctx = popContext();
773-
return createType(createWithChildren(Node::Kind::TypeAlias, Ctx, Name));
774-
}
775-
776770
NodePointer Demangler::demangleExtensionContext() {
777771
NodePointer GenSig = popNode(Node::Kind::DependentGenericSignature);
778772
NodePointer Module = popModule();

lib/Demangling/Remangler.cpp

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -271,7 +271,7 @@ class Remangler {
271271
}
272272

273273
void mangleAnyNominalType(Node *node);
274-
void mangleNominalType(Node *node, char TypeOp);
274+
void mangleAnyGenericType(Node *node, char TypeOp);
275275
void mangleGenericArgs(Node *node, char &Separator);
276276

277277
#define NODE(ID) \
@@ -413,7 +413,7 @@ std::pair<int, Node *> Remangler::mangleConstrainedType(Node *node) {
413413
return {(int)Chain.size(), node};
414414
}
415415

416-
void Remangler::mangleNominalType(Node *node, char TypeOp) {
416+
void Remangler::mangleAnyGenericType(Node *node, char TypeOp) {
417417
SubstitutionEntry entry;
418418
if (trySubstitution(node, entry)) return;
419419
mangleChildNodes(node);
@@ -436,9 +436,9 @@ void Remangler::mangleAnyNominalType(Node *node) {
436436
return;
437437
}
438438
switch (node->getKind()) {
439-
case Node::Kind::Structure: return mangleNominalType(node, 'V');
440-
case Node::Kind::Enum: return mangleNominalType(node, 'O');
441-
case Node::Kind::Class: return mangleNominalType(node, 'C');
439+
case Node::Kind::Structure: return mangleAnyGenericType(node, 'V');
440+
case Node::Kind::Enum: return mangleAnyGenericType(node, 'O');
441+
case Node::Kind::Class: return mangleAnyGenericType(node, 'C');
442442
default:
443443
unreachable("bad nominal type kind");
444444
}
@@ -1380,7 +1380,7 @@ void Remangler::manglePrivateDeclName(Node *node) {
13801380
}
13811381

13821382
void Remangler::mangleProtocol(Node *node) {
1383-
mangleNominalType(node, 'P');
1383+
mangleAnyGenericType(node, 'P');
13841384
}
13851385

13861386
void Remangler::mangleProtocolConformance(Node *node) {
@@ -1540,8 +1540,7 @@ void Remangler::mangleType(Node *node) {
15401540
}
15411541

15421542
void Remangler::mangleTypeAlias(Node *node) {
1543-
mangleChildNodes(node);
1544-
Buffer << 'a';
1543+
mangleAnyGenericType(node, 'a');
15451544
}
15461545

15471546
void Remangler::mangleTypeList(Node *node) {

0 commit comments

Comments
 (0)