Skip to content

Commit 1b51012

Browse files
committed
Factor the mangling of generic parameter lists (i.e., their
archetypes) into a single place, and cope with outer parameter lists. Incrementally stepping toward IRgen support for nested generics. Swift SVN r2570
1 parent 051a7df commit 1b51012

File tree

1 file changed

+45
-39
lines changed

1 file changed

+45
-39
lines changed

lib/IRGen/Mangle.cpp

Lines changed: 45 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
#include "swift/AST/Decl.h"
2121
#include "swift/AST/Module.h"
2222
#include "llvm/ADT/DenseMap.h"
23+
#include "llvm/Support/SaveAndRestore.h"
2324
#include "llvm/ADT/StringRef.h"
2425
#include "llvm/Support/raw_ostream.h"
2526
#include "llvm/Support/ErrorHandling.h"
@@ -103,6 +104,9 @@ namespace {
103104
void mangleDeclContext(DeclContext *ctx);
104105
void mangleIdentifier(Identifier ident);
105106
void mangleGetterOrSetterContext(FuncDecl *fn);
107+
void manglePolymorphicType(const GenericParamList *genericParams, Type T,
108+
ExplosionKind explosion, unsigned uncurryLevel,
109+
bool mangleAsFunction);
106110
bool tryMangleStandardSubstitution(NominalTypeDecl *type);
107111
bool tryMangleSubstitution(void *ptr);
108112
void addSubstitution(void *ptr);
@@ -249,6 +253,43 @@ void Mangler::mangleGetterOrSetterContext(FuncDecl *func) {
249253
}
250254
}
251255

256+
void Mangler::manglePolymorphicType(const GenericParamList *genericParams,
257+
Type T, ExplosionKind explosion,
258+
unsigned uncurryLevel,
259+
bool mangleAsFunction) {
260+
SmallVector<const GenericParamList *, 2> paramLists;
261+
for (; genericParams; genericParams = genericParams->getOuterParameters())
262+
paramLists.push_back(genericParams);
263+
264+
// FIXME: Prefix?
265+
llvm::SaveAndRestore<unsigned> oldArchetypesDepth(ArchetypesDepth);
266+
for (auto gp = paramLists.rbegin(), gpEnd = paramLists.rend(); gp != gpEnd;
267+
++gp) {
268+
ArchetypesDepth++;
269+
unsigned index = 0;
270+
// FIXME: Only mangle the archetypes and protocol requirements that
271+
// matter, rather than everything.
272+
for (auto archetype : (*gp)->getAllArchetypes()) {
273+
// Remember the current depth and level.
274+
ArchetypeInfo info;
275+
info.Depth = ArchetypesDepth;
276+
info.Index = index++;
277+
Archetypes.insert(std::make_pair(archetype, info));
278+
279+
// Mangle this type parameter.
280+
// <generic-parameter> ::= <protocol-list> _
281+
mangleProtocolList(archetype->getConformsTo());
282+
Buffer << '_';
283+
}
284+
}
285+
Buffer << '_';
286+
287+
if (mangleAsFunction)
288+
mangleFunctionType(cast<AnyFunctionType>(T), explosion, uncurryLevel);
289+
else
290+
mangleType(T, explosion, uncurryLevel);
291+
}
292+
252293
void Mangler::mangleDeclName(ValueDecl *decl, IncludeType includeType) {
253294
// decl ::= context identifier
254295
mangleDeclContext(decl->getDeclContext());
@@ -268,25 +309,8 @@ void Mangler::mangleDeclType(ValueDecl *decl, ExplosionKind explosion,
268309
if (isa<SubscriptDecl>(decl)) {
269310
auto genericParams = decl->getDeclContext()->getGenericParamsOfContext();
270311
if (genericParams) {
271-
// FIXME: Prefix?
272-
ArchetypesDepth++;
273-
unsigned index = 0;
274-
// FIXME: Only mangle the archetypes and protocol requirements that
275-
// matter, rather than everything.
276-
for (auto archetype : genericParams->getAllArchetypes()) {
277-
// Remember the current depth and level.
278-
ArchetypeInfo info;
279-
info.Depth = ArchetypesDepth;
280-
info.Index = index++;
281-
Archetypes.insert(std::make_pair(archetype, info));
282-
283-
// Mangle this type parameter.
284-
// <generic-parameter> ::= <protocol-list> _
285-
mangleProtocolList(archetype->getConformsTo());
286-
Buffer << '_';
287-
}
288-
mangleType(decl->getType(), explosion, uncurryLevel);
289-
ArchetypesDepth--;
312+
manglePolymorphicType(genericParams, decl->getType(), explosion,
313+
uncurryLevel, /*mangleAsFunction=*/false);
290314
return;
291315
}
292316
}
@@ -422,26 +446,8 @@ void Mangler::mangleType(Type type, ExplosionKind explosion,
422446
// The nested type is always a function type.
423447
PolymorphicFunctionType *fn = cast<PolymorphicFunctionType>(base);
424448
Buffer << 'U';
425-
426-
ArchetypesDepth++;
427-
unsigned index = 0;
428-
// FIXME: Only mangle the archetypes and protocol requirements that
429-
// matter, rather than everything.
430-
for (auto archetype : fn->getGenericParams().getAllArchetypes()) {
431-
// Remember the current depth and level.
432-
ArchetypeInfo info;
433-
info.Depth = ArchetypesDepth;
434-
info.Index = index++;
435-
Archetypes.insert(std::make_pair(archetype, info));
436-
437-
// Mangle this type parameter.
438-
// <generic-parameter> ::= <protocol-list> _
439-
mangleProtocolList(archetype->getConformsTo());
440-
Buffer << '_';
441-
}
442-
Buffer << '_';
443-
mangleFunctionType(fn, explosion, uncurryLevel);
444-
ArchetypesDepth--;
449+
manglePolymorphicType(&fn->getGenericParams(), fn, explosion, uncurryLevel,
450+
/*mangleAsFunction=*/true);
445451
return;
446452
}
447453

0 commit comments

Comments
 (0)