Skip to content

Commit 562ce15

Browse files
committed
[demangler] Avoid special-subst code duplication
We need to expand special substitutions in four different ways. This refactors to only have one conversion from enum to string, and derive the other 3 needs off that. The SpecialSubstitution node is derived from the ExpandedSpecialSubstitution. While this may seem unintuitive, it works out quite well, as SpecialSubstitution can then use the former's getBaseName and remove an unneeded 'basic_' prefix, for those substitutions that are instantiations (to known typedef). Similarly all those instantiations use the same set of template arguments (with 'basic_string', getting an additional 'allocator' arg). Expansion tests were added in D123134, and remain unchanged. Reviewed By: MaskRay, dblaikie Differential Revision: https://reviews.llvm.org/D125257
1 parent 89d4904 commit 562ce15

File tree

2 files changed

+74
-146
lines changed

2 files changed

+74
-146
lines changed

libcxxabi/src/demangle/ItaniumDemangle.h

Lines changed: 37 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -1506,15 +1506,25 @@ enum class SpecialSubKind {
15061506
iostream,
15071507
};
15081508

1509-
class ExpandedSpecialSubstitution final : public Node {
1509+
class SpecialSubstitution;
1510+
class ExpandedSpecialSubstitution : public Node {
1511+
protected:
15101512
SpecialSubKind SSK;
15111513

1514+
ExpandedSpecialSubstitution(SpecialSubKind SSK_, Kind K_)
1515+
: Node(K_), SSK(SSK_) {}
15121516
public:
15131517
ExpandedSpecialSubstitution(SpecialSubKind SSK_)
1514-
: Node(KExpandedSpecialSubstitution), SSK(SSK_) {}
1518+
: ExpandedSpecialSubstitution(SSK_, KExpandedSpecialSubstitution) {}
1519+
inline ExpandedSpecialSubstitution(SpecialSubstitution const *);
15151520

15161521
template<typename Fn> void match(Fn F) const { F(SSK); }
15171522

1523+
protected:
1524+
bool isInstantiation() const {
1525+
return unsigned(SSK) >= unsigned(SpecialSubKind::string);
1526+
}
1527+
15181528
StringView getBaseName() const override {
15191529
switch (SSK) {
15201530
case SpecialSubKind::allocator:
@@ -1533,82 +1543,44 @@ class ExpandedSpecialSubstitution final : public Node {
15331543
DEMANGLE_UNREACHABLE;
15341544
}
15351545

1546+
private:
15361547
void printLeft(OutputBuffer &OB) const override {
1537-
switch (SSK) {
1538-
case SpecialSubKind::allocator:
1539-
OB += "std::allocator";
1540-
break;
1541-
case SpecialSubKind::basic_string:
1542-
OB += "std::basic_string";
1543-
break;
1544-
case SpecialSubKind::string:
1545-
OB += "std::basic_string<char, std::char_traits<char>, "
1546-
"std::allocator<char>>";
1547-
break;
1548-
case SpecialSubKind::istream:
1549-
OB += "std::basic_istream<char, std::char_traits<char>>";
1550-
break;
1551-
case SpecialSubKind::ostream:
1552-
OB += "std::basic_ostream<char, std::char_traits<char>>";
1553-
break;
1554-
case SpecialSubKind::iostream:
1555-
OB += "std::basic_iostream<char, std::char_traits<char>>";
1556-
break;
1548+
OB << "std::" << getBaseName();
1549+
if (isInstantiation()) {
1550+
OB << "<char, std::char_traits<char>";
1551+
if (SSK == SpecialSubKind::string)
1552+
OB << ", std::allocator<char>";
1553+
OB << ">";
15571554
}
15581555
}
15591556
};
15601557

1561-
class SpecialSubstitution final : public Node {
1558+
class SpecialSubstitution final : public ExpandedSpecialSubstitution {
15621559
public:
1563-
SpecialSubKind SSK;
1564-
15651560
SpecialSubstitution(SpecialSubKind SSK_)
1566-
: Node(KSpecialSubstitution), SSK(SSK_) {}
1561+
: ExpandedSpecialSubstitution(SSK_, KSpecialSubstitution) {}
15671562

15681563
template<typename Fn> void match(Fn F) const { F(SSK); }
15691564

15701565
StringView getBaseName() const override {
1571-
switch (SSK) {
1572-
case SpecialSubKind::allocator:
1573-
return StringView("allocator");
1574-
case SpecialSubKind::basic_string:
1575-
return StringView("basic_string");
1576-
case SpecialSubKind::string:
1577-
return StringView("string");
1578-
case SpecialSubKind::istream:
1579-
return StringView("istream");
1580-
case SpecialSubKind::ostream:
1581-
return StringView("ostream");
1582-
case SpecialSubKind::iostream:
1583-
return StringView("iostream");
1566+
auto SV = ExpandedSpecialSubstitution::getBaseName ();
1567+
if (isInstantiation()) {
1568+
// The instantiations are typedefs that drop the "basic_" prefix.
1569+
assert(SV.startsWith("basic_"));
1570+
SV = SV.dropFront(sizeof("basic_") - 1);
15841571
}
1585-
DEMANGLE_UNREACHABLE;
1572+
return SV;
15861573
}
15871574

15881575
void printLeft(OutputBuffer &OB) const override {
1589-
switch (SSK) {
1590-
case SpecialSubKind::allocator:
1591-
OB += "std::allocator";
1592-
break;
1593-
case SpecialSubKind::basic_string:
1594-
OB += "std::basic_string";
1595-
break;
1596-
case SpecialSubKind::string:
1597-
OB += "std::string";
1598-
break;
1599-
case SpecialSubKind::istream:
1600-
OB += "std::istream";
1601-
break;
1602-
case SpecialSubKind::ostream:
1603-
OB += "std::ostream";
1604-
break;
1605-
case SpecialSubKind::iostream:
1606-
OB += "std::iostream";
1607-
break;
1608-
}
1576+
OB << "std::" << getBaseName();
16091577
}
16101578
};
16111579

1580+
inline ExpandedSpecialSubstitution::ExpandedSpecialSubstitution(
1581+
SpecialSubstitution const *SS)
1582+
: ExpandedSpecialSubstitution(SS->SSK) {}
1583+
16121584
class CtorDtorName final : public Node {
16131585
const Node *Basename;
16141586
const bool IsDtor;
@@ -3128,19 +3100,11 @@ Node *
31283100
AbstractManglingParser<Derived, Alloc>::parseCtorDtorName(Node *&SoFar,
31293101
NameState *State) {
31303102
if (SoFar->getKind() == Node::KSpecialSubstitution) {
3131-
auto SSK = static_cast<SpecialSubstitution *>(SoFar)->SSK;
3132-
switch (SSK) {
3133-
case SpecialSubKind::string:
3134-
case SpecialSubKind::istream:
3135-
case SpecialSubKind::ostream:
3136-
case SpecialSubKind::iostream:
3137-
SoFar = make<ExpandedSpecialSubstitution>(SSK);
3138-
if (!SoFar)
3139-
return nullptr;
3140-
break;
3141-
default:
3142-
break;
3143-
}
3103+
// Expand the special substitution.
3104+
SoFar = make<ExpandedSpecialSubstitution>(
3105+
static_cast<SpecialSubstitution *>(SoFar));
3106+
if (!SoFar)
3107+
return nullptr;
31443108
}
31453109

31463110
if (consumeIf('C')) {

llvm/include/llvm/Demangle/ItaniumDemangle.h

Lines changed: 37 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -1506,15 +1506,25 @@ enum class SpecialSubKind {
15061506
iostream,
15071507
};
15081508

1509-
class ExpandedSpecialSubstitution final : public Node {
1509+
class SpecialSubstitution;
1510+
class ExpandedSpecialSubstitution : public Node {
1511+
protected:
15101512
SpecialSubKind SSK;
15111513

1514+
ExpandedSpecialSubstitution(SpecialSubKind SSK_, Kind K_)
1515+
: Node(K_), SSK(SSK_) {}
15121516
public:
15131517
ExpandedSpecialSubstitution(SpecialSubKind SSK_)
1514-
: Node(KExpandedSpecialSubstitution), SSK(SSK_) {}
1518+
: ExpandedSpecialSubstitution(SSK_, KExpandedSpecialSubstitution) {}
1519+
inline ExpandedSpecialSubstitution(SpecialSubstitution const *);
15151520

15161521
template<typename Fn> void match(Fn F) const { F(SSK); }
15171522

1523+
protected:
1524+
bool isInstantiation() const {
1525+
return unsigned(SSK) >= unsigned(SpecialSubKind::string);
1526+
}
1527+
15181528
StringView getBaseName() const override {
15191529
switch (SSK) {
15201530
case SpecialSubKind::allocator:
@@ -1533,82 +1543,44 @@ class ExpandedSpecialSubstitution final : public Node {
15331543
DEMANGLE_UNREACHABLE;
15341544
}
15351545

1546+
private:
15361547
void printLeft(OutputBuffer &OB) const override {
1537-
switch (SSK) {
1538-
case SpecialSubKind::allocator:
1539-
OB += "std::allocator";
1540-
break;
1541-
case SpecialSubKind::basic_string:
1542-
OB += "std::basic_string";
1543-
break;
1544-
case SpecialSubKind::string:
1545-
OB += "std::basic_string<char, std::char_traits<char>, "
1546-
"std::allocator<char>>";
1547-
break;
1548-
case SpecialSubKind::istream:
1549-
OB += "std::basic_istream<char, std::char_traits<char>>";
1550-
break;
1551-
case SpecialSubKind::ostream:
1552-
OB += "std::basic_ostream<char, std::char_traits<char>>";
1553-
break;
1554-
case SpecialSubKind::iostream:
1555-
OB += "std::basic_iostream<char, std::char_traits<char>>";
1556-
break;
1548+
OB << "std::" << getBaseName();
1549+
if (isInstantiation()) {
1550+
OB << "<char, std::char_traits<char>";
1551+
if (SSK == SpecialSubKind::string)
1552+
OB << ", std::allocator<char>";
1553+
OB << ">";
15571554
}
15581555
}
15591556
};
15601557

1561-
class SpecialSubstitution final : public Node {
1558+
class SpecialSubstitution final : public ExpandedSpecialSubstitution {
15621559
public:
1563-
SpecialSubKind SSK;
1564-
15651560
SpecialSubstitution(SpecialSubKind SSK_)
1566-
: Node(KSpecialSubstitution), SSK(SSK_) {}
1561+
: ExpandedSpecialSubstitution(SSK_, KSpecialSubstitution) {}
15671562

15681563
template<typename Fn> void match(Fn F) const { F(SSK); }
15691564

15701565
StringView getBaseName() const override {
1571-
switch (SSK) {
1572-
case SpecialSubKind::allocator:
1573-
return StringView("allocator");
1574-
case SpecialSubKind::basic_string:
1575-
return StringView("basic_string");
1576-
case SpecialSubKind::string:
1577-
return StringView("string");
1578-
case SpecialSubKind::istream:
1579-
return StringView("istream");
1580-
case SpecialSubKind::ostream:
1581-
return StringView("ostream");
1582-
case SpecialSubKind::iostream:
1583-
return StringView("iostream");
1566+
auto SV = ExpandedSpecialSubstitution::getBaseName ();
1567+
if (isInstantiation()) {
1568+
// The instantiations are typedefs that drop the "basic_" prefix.
1569+
assert(SV.startsWith("basic_"));
1570+
SV = SV.dropFront(sizeof("basic_") - 1);
15841571
}
1585-
DEMANGLE_UNREACHABLE;
1572+
return SV;
15861573
}
15871574

15881575
void printLeft(OutputBuffer &OB) const override {
1589-
switch (SSK) {
1590-
case SpecialSubKind::allocator:
1591-
OB += "std::allocator";
1592-
break;
1593-
case SpecialSubKind::basic_string:
1594-
OB += "std::basic_string";
1595-
break;
1596-
case SpecialSubKind::string:
1597-
OB += "std::string";
1598-
break;
1599-
case SpecialSubKind::istream:
1600-
OB += "std::istream";
1601-
break;
1602-
case SpecialSubKind::ostream:
1603-
OB += "std::ostream";
1604-
break;
1605-
case SpecialSubKind::iostream:
1606-
OB += "std::iostream";
1607-
break;
1608-
}
1576+
OB << "std::" << getBaseName();
16091577
}
16101578
};
16111579

1580+
inline ExpandedSpecialSubstitution::ExpandedSpecialSubstitution(
1581+
SpecialSubstitution const *SS)
1582+
: ExpandedSpecialSubstitution(SS->SSK) {}
1583+
16121584
class CtorDtorName final : public Node {
16131585
const Node *Basename;
16141586
const bool IsDtor;
@@ -3128,19 +3100,11 @@ Node *
31283100
AbstractManglingParser<Derived, Alloc>::parseCtorDtorName(Node *&SoFar,
31293101
NameState *State) {
31303102
if (SoFar->getKind() == Node::KSpecialSubstitution) {
3131-
auto SSK = static_cast<SpecialSubstitution *>(SoFar)->SSK;
3132-
switch (SSK) {
3133-
case SpecialSubKind::string:
3134-
case SpecialSubKind::istream:
3135-
case SpecialSubKind::ostream:
3136-
case SpecialSubKind::iostream:
3137-
SoFar = make<ExpandedSpecialSubstitution>(SSK);
3138-
if (!SoFar)
3139-
return nullptr;
3140-
break;
3141-
default:
3142-
break;
3143-
}
3103+
// Expand the special substitution.
3104+
SoFar = make<ExpandedSpecialSubstitution>(
3105+
static_cast<SpecialSubstitution *>(SoFar));
3106+
if (!SoFar)
3107+
return nullptr;
31443108
}
31453109

31463110
if (consumeIf('C')) {

0 commit comments

Comments
 (0)