Skip to content

Commit 97f1fac

Browse files
committed
Mangling: refactoring: use meta-programming for value witness mangling/demangling/remangling
Also add the missing DestructiveInjectEnumTag entry.
1 parent f52f355 commit 97f1fac

File tree

5 files changed

+64
-115
lines changed

5 files changed

+64
-115
lines changed

include/swift/Basic/Demangle.h

Lines changed: 3 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -108,27 +108,9 @@ static inline char encodeSpecializationPass(SpecializationPass Pass) {
108108
}
109109

110110
enum class ValueWitnessKind {
111-
AllocateBuffer,
112-
AssignWithCopy,
113-
AssignWithTake,
114-
DeallocateBuffer,
115-
Destroy,
116-
DestroyBuffer,
117-
InitializeBufferWithCopyOfBuffer,
118-
InitializeBufferWithCopy,
119-
InitializeWithCopy,
120-
InitializeBufferWithTake,
121-
InitializeWithTake,
122-
ProjectBuffer,
123-
InitializeBufferWithTakeOfBuffer,
124-
DestroyArray,
125-
InitializeArrayWithCopy,
126-
InitializeArrayWithTakeFrontToBack,
127-
InitializeArrayWithTakeBackToFront,
128-
StoreExtraInhabitant,
129-
GetExtraInhabitantIndex,
130-
GetEnumTag,
131-
DestructiveProjectEnumData,
111+
#define VALUE_WITNESS(MANGLING, NAME) \
112+
NAME,
113+
#include "swift/Basic/ValueWitnessMangling.def"
132114
};
133115

134116
enum class Directness {
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
//===-- ValueWitnessMangling.def - VW Mangling Metaprogramming --*- C++ -*-===//
2+
//
3+
// This source file is part of the Swift.org open source project
4+
//
5+
// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors
6+
// Licensed under Apache License v2.0 with Runtime Library Exception
7+
//
8+
// See http://swift.org/LICENSE.txt for license information
9+
// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
10+
//
11+
//===----------------------------------------------------------------------===//
12+
13+
/// VALUE_WITNESS(MANGLING, NAME)
14+
/// The 2-character MANGLING for a value witness NAME.
15+
16+
VALUE_WITNESS(al, AllocateBuffer)
17+
VALUE_WITNESS(ca, AssignWithCopy)
18+
VALUE_WITNESS(ta, AssignWithTake)
19+
VALUE_WITNESS(de, DeallocateBuffer)
20+
VALUE_WITNESS(xx, Destroy)
21+
VALUE_WITNESS(XX, DestroyBuffer)
22+
VALUE_WITNESS(Xx, DestroyArray)
23+
VALUE_WITNESS(CP, InitializeBufferWithCopyOfBuffer)
24+
VALUE_WITNESS(Cp, InitializeBufferWithCopy)
25+
VALUE_WITNESS(cp, InitializeWithCopy)
26+
VALUE_WITNESS(Tk, InitializeBufferWithTake)
27+
VALUE_WITNESS(tk, InitializeWithTake)
28+
VALUE_WITNESS(pr, ProjectBuffer)
29+
VALUE_WITNESS(TK, InitializeBufferWithTakeOfBuffer)
30+
VALUE_WITNESS(Cc, InitializeArrayWithCopy)
31+
VALUE_WITNESS(Tt, InitializeArrayWithTakeFrontToBack)
32+
VALUE_WITNESS(tT, InitializeArrayWithTakeBackToFront)
33+
VALUE_WITNESS(xs, StoreExtraInhabitant)
34+
VALUE_WITNESS(xg, GetExtraInhabitantIndex)
35+
VALUE_WITNESS(ug, GetEnumTag)
36+
VALUE_WITNESS(up, DestructiveProjectEnumData)
37+
VALUE_WITNESS(ui, DestructiveInjectEnumTag)
38+
39+
#undef VALUE_WITNESS

lib/Basic/Demangle.cpp

Lines changed: 11 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -284,6 +284,8 @@ static StringRef toString(ValueWitnessKind k) {
284284
return "getEnumTag";
285285
case ValueWitnessKind::DestructiveProjectEnumData:
286286
return "destructiveProjectEnumData";
287+
case ValueWitnessKind::DestructiveInjectEnumTag:
288+
return "destructiveInjectEnumTag";
287289
}
288290
unreachable("bad value witness kind");
289291
}
@@ -409,54 +411,19 @@ class Demangler {
409411
}
410412

411413
Optional<ValueWitnessKind> demangleValueWitnessKind() {
414+
char Code[2];
412415
if (!Mangled)
413416
return None;
414-
char c1 = Mangled.next();
417+
Code[0] = Mangled.next();
415418
if (!Mangled)
416419
return None;
417-
char c2 = Mangled.next();
418-
if (c1 == 'a' && c2 == 'l')
419-
return ValueWitnessKind::AllocateBuffer;
420-
if (c1 == 'c' && c2 == 'a')
421-
return ValueWitnessKind::AssignWithCopy;
422-
if (c1 == 't' && c2 == 'a')
423-
return ValueWitnessKind::AssignWithTake;
424-
if (c1 == 'd' && c2 == 'e')
425-
return ValueWitnessKind::DeallocateBuffer;
426-
if (c1 == 'x' && c2 == 'x')
427-
return ValueWitnessKind::Destroy;
428-
if (c1 == 'X' && c2 == 'X')
429-
return ValueWitnessKind::DestroyBuffer;
430-
if (c1 == 'C' && c2 == 'P')
431-
return ValueWitnessKind::InitializeBufferWithCopyOfBuffer;
432-
if (c1 == 'C' && c2 == 'p')
433-
return ValueWitnessKind::InitializeBufferWithCopy;
434-
if (c1 == 'c' && c2 == 'p')
435-
return ValueWitnessKind::InitializeWithCopy;
436-
if (c1 == 'C' && c2 == 'c')
437-
return ValueWitnessKind::InitializeArrayWithCopy;
438-
if (c1 == 'T' && c2 == 'K')
439-
return ValueWitnessKind::InitializeBufferWithTakeOfBuffer;
440-
if (c1 == 'T' && c2 == 'k')
441-
return ValueWitnessKind::InitializeBufferWithTake;
442-
if (c1 == 't' && c2 == 'k')
443-
return ValueWitnessKind::InitializeWithTake;
444-
if (c1 == 'T' && c2 == 't')
445-
return ValueWitnessKind::InitializeArrayWithTakeFrontToBack;
446-
if (c1 == 't' && c2 == 'T')
447-
return ValueWitnessKind::InitializeArrayWithTakeBackToFront;
448-
if (c1 == 'p' && c2 == 'r')
449-
return ValueWitnessKind::ProjectBuffer;
450-
if (c1 == 'X' && c2 == 'x')
451-
return ValueWitnessKind::DestroyArray;
452-
if (c1 == 'x' && c2 == 's')
453-
return ValueWitnessKind::StoreExtraInhabitant;
454-
if (c1 == 'x' && c2 == 'g')
455-
return ValueWitnessKind::GetExtraInhabitantIndex;
456-
if (c1 == 'u' && c2 == 'g')
457-
return ValueWitnessKind::GetEnumTag;
458-
if (c1 == 'u' && c2 == 'p')
459-
return ValueWitnessKind::DestructiveProjectEnumData;
420+
Code[1] = Mangled.next();
421+
422+
StringRef CodeStr(Code, 2);
423+
#define VALUE_WITNESS(MANGLING, NAME) \
424+
if (CodeStr == #MANGLING) return ValueWitnessKind::NAME;
425+
#include "swift/Basic/ValueWitnessMangling.def"
426+
460427
return None;
461428
}
462429

lib/Basic/Remangle.cpp

Lines changed: 7 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -653,33 +653,13 @@ void Remangler::mangleDirectness(Node *node) {
653653
}
654654

655655
void Remangler::mangleValueWitness(Node *node) {
656-
auto getString = [](ValueWitnessKind kind) -> StringRef {
657-
switch (kind) {
658-
case ValueWitnessKind::AllocateBuffer: return "al";
659-
case ValueWitnessKind::AssignWithCopy: return "ca";
660-
case ValueWitnessKind::AssignWithTake: return "ta";
661-
case ValueWitnessKind::DeallocateBuffer: return "de";
662-
case ValueWitnessKind::Destroy: return "xx";
663-
case ValueWitnessKind::DestroyBuffer: return "XX";
664-
case ValueWitnessKind::InitializeBufferWithCopyOfBuffer: return "CP";
665-
case ValueWitnessKind::InitializeBufferWithCopy: return "Cp";
666-
case ValueWitnessKind::InitializeWithCopy: return "cp";
667-
case ValueWitnessKind::InitializeBufferWithTake: return "Tk";
668-
case ValueWitnessKind::InitializeWithTake: return "tk";
669-
case ValueWitnessKind::ProjectBuffer: return "pr";
670-
case ValueWitnessKind::InitializeBufferWithTakeOfBuffer: return "TK";
671-
case ValueWitnessKind::DestroyArray: return "Xx";
672-
case ValueWitnessKind::InitializeArrayWithCopy: return "Cc";
673-
case ValueWitnessKind::InitializeArrayWithTakeFrontToBack: return "Tt";
674-
case ValueWitnessKind::InitializeArrayWithTakeBackToFront: return "tT";
675-
case ValueWitnessKind::StoreExtraInhabitant: return "xs";
676-
case ValueWitnessKind::GetExtraInhabitantIndex: return "xg";
677-
case ValueWitnessKind::GetEnumTag: return "ug";
678-
case ValueWitnessKind::DestructiveProjectEnumData: return "up";
679-
}
680-
unreachable("bad value witness kind");
681-
};
682-
Out << 'w' << getString(ValueWitnessKind(node->getIndex()));
656+
const char *Code = nullptr;
657+
switch (ValueWitnessKind(node->getIndex())) {
658+
#define VALUE_WITNESS(MANGLING, NAME) \
659+
case ValueWitnessKind::NAME: Code = #MANGLING; break;
660+
#include "swift/Basic/ValueWitnessMangling.def"
661+
}
662+
Out << 'w' << Code;
683663
mangleSingleChildNode(node); // type
684664
}
685665

lib/IRGen/Linking.cpp

Lines changed: 4 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -34,29 +34,10 @@ static StringRef mangleValueWitness(ValueWitness witness) {
3434
// opposed to objects) in the arguments. That doesn't serve any
3535
// direct purpose, but it's neat.
3636
switch (witness) {
37-
case ValueWitness::AllocateBuffer: return "al";
38-
case ValueWitness::AssignWithCopy: return "ca";
39-
case ValueWitness::AssignWithTake: return "ta";
40-
case ValueWitness::DeallocateBuffer: return "de";
41-
case ValueWitness::Destroy: return "xx";
42-
case ValueWitness::DestroyBuffer: return "XX";
43-
case ValueWitness::DestroyArray: return "Xx";
44-
case ValueWitness::InitializeBufferWithCopyOfBuffer: return "CP";
45-
case ValueWitness::InitializeBufferWithCopy: return "Cp";
46-
case ValueWitness::InitializeWithCopy: return "cp";
47-
case ValueWitness::InitializeBufferWithTake: return "Tk";
48-
case ValueWitness::InitializeWithTake: return "tk";
49-
case ValueWitness::ProjectBuffer: return "pr";
50-
case ValueWitness::InitializeBufferWithTakeOfBuffer: return "TK";
51-
case ValueWitness::InitializeArrayWithCopy: return "Cc";
52-
case ValueWitness::InitializeArrayWithTakeFrontToBack: return "Tt";
53-
case ValueWitness::InitializeArrayWithTakeBackToFront: return "tT";
54-
case ValueWitness::StoreExtraInhabitant: return "xs";
55-
case ValueWitness::GetExtraInhabitantIndex: return "xg";
56-
case ValueWitness::GetEnumTag: return "ug";
57-
case ValueWitness::DestructiveProjectEnumData: return "up";
58-
case ValueWitness::DestructiveInjectEnumTag: return "ui";
59-
37+
#define VALUE_WITNESS(MANGLING, NAME) \
38+
case ValueWitness::NAME: return #MANGLING;
39+
#include "swift/Basic/ValueWitnessMangling.def"
40+
6041
case ValueWitness::Size:
6142
case ValueWitness::Flags:
6243
case ValueWitness::Stride:

0 commit comments

Comments
 (0)