Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/llvm/llvm-project.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNathan Sidwell <nathan@acm.org>2022-03-28 22:55:45 +0300
committerNathan Sidwell <nathan@acm.org>2022-05-13 14:35:29 +0300
commit562ce15924560d14f7062173cbdc6a9cd778e2eb (patch)
tree1dc7982e3b76bc36e8f3aa8352689da725f13264 /libcxxabi/src/demangle
parent89d4904541106172e307efc98fbed5d8a86c4342 (diff)
[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
Diffstat (limited to 'libcxxabi/src/demangle')
-rw-r--r--libcxxabi/src/demangle/ItaniumDemangle.h110
1 files changed, 37 insertions, 73 deletions
diff --git a/libcxxabi/src/demangle/ItaniumDemangle.h b/libcxxabi/src/demangle/ItaniumDemangle.h
index fa12a0a6d782..beece93b21d4 100644
--- a/libcxxabi/src/demangle/ItaniumDemangle.h
+++ b/libcxxabi/src/demangle/ItaniumDemangle.h
@@ -1506,15 +1506,25 @@ enum class SpecialSubKind {
iostream,
};
-class ExpandedSpecialSubstitution final : public Node {
+class SpecialSubstitution;
+class ExpandedSpecialSubstitution : public Node {
+protected:
SpecialSubKind SSK;
+ ExpandedSpecialSubstitution(SpecialSubKind SSK_, Kind K_)
+ : Node(K_), SSK(SSK_) {}
public:
ExpandedSpecialSubstitution(SpecialSubKind SSK_)
- : Node(KExpandedSpecialSubstitution), SSK(SSK_) {}
+ : ExpandedSpecialSubstitution(SSK_, KExpandedSpecialSubstitution) {}
+ inline ExpandedSpecialSubstitution(SpecialSubstitution const *);
template<typename Fn> void match(Fn F) const { F(SSK); }
+protected:
+ bool isInstantiation() const {
+ return unsigned(SSK) >= unsigned(SpecialSubKind::string);
+ }
+
StringView getBaseName() const override {
switch (SSK) {
case SpecialSubKind::allocator:
@@ -1533,82 +1543,44 @@ public:
DEMANGLE_UNREACHABLE;
}
+private:
void printLeft(OutputBuffer &OB) const override {
- switch (SSK) {
- case SpecialSubKind::allocator:
- OB += "std::allocator";
- break;
- case SpecialSubKind::basic_string:
- OB += "std::basic_string";
- break;
- case SpecialSubKind::string:
- OB += "std::basic_string<char, std::char_traits<char>, "
- "std::allocator<char>>";
- break;
- case SpecialSubKind::istream:
- OB += "std::basic_istream<char, std::char_traits<char>>";
- break;
- case SpecialSubKind::ostream:
- OB += "std::basic_ostream<char, std::char_traits<char>>";
- break;
- case SpecialSubKind::iostream:
- OB += "std::basic_iostream<char, std::char_traits<char>>";
- break;
+ OB << "std::" << getBaseName();
+ if (isInstantiation()) {
+ OB << "<char, std::char_traits<char>";
+ if (SSK == SpecialSubKind::string)
+ OB << ", std::allocator<char>";
+ OB << ">";
}
}
};
-class SpecialSubstitution final : public Node {
+class SpecialSubstitution final : public ExpandedSpecialSubstitution {
public:
- SpecialSubKind SSK;
-
SpecialSubstitution(SpecialSubKind SSK_)
- : Node(KSpecialSubstitution), SSK(SSK_) {}
+ : ExpandedSpecialSubstitution(SSK_, KSpecialSubstitution) {}
template<typename Fn> void match(Fn F) const { F(SSK); }
StringView getBaseName() const override {
- switch (SSK) {
- case SpecialSubKind::allocator:
- return StringView("allocator");
- case SpecialSubKind::basic_string:
- return StringView("basic_string");
- case SpecialSubKind::string:
- return StringView("string");
- case SpecialSubKind::istream:
- return StringView("istream");
- case SpecialSubKind::ostream:
- return StringView("ostream");
- case SpecialSubKind::iostream:
- return StringView("iostream");
+ auto SV = ExpandedSpecialSubstitution::getBaseName ();
+ if (isInstantiation()) {
+ // The instantiations are typedefs that drop the "basic_" prefix.
+ assert(SV.startsWith("basic_"));
+ SV = SV.dropFront(sizeof("basic_") - 1);
}
- DEMANGLE_UNREACHABLE;
+ return SV;
}
void printLeft(OutputBuffer &OB) const override {
- switch (SSK) {
- case SpecialSubKind::allocator:
- OB += "std::allocator";
- break;
- case SpecialSubKind::basic_string:
- OB += "std::basic_string";
- break;
- case SpecialSubKind::string:
- OB += "std::string";
- break;
- case SpecialSubKind::istream:
- OB += "std::istream";
- break;
- case SpecialSubKind::ostream:
- OB += "std::ostream";
- break;
- case SpecialSubKind::iostream:
- OB += "std::iostream";
- break;
- }
+ OB << "std::" << getBaseName();
}
};
+inline ExpandedSpecialSubstitution::ExpandedSpecialSubstitution(
+ SpecialSubstitution const *SS)
+ : ExpandedSpecialSubstitution(SS->SSK) {}
+
class CtorDtorName final : public Node {
const Node *Basename;
const bool IsDtor;
@@ -3128,19 +3100,11 @@ Node *
AbstractManglingParser<Derived, Alloc>::parseCtorDtorName(Node *&SoFar,
NameState *State) {
if (SoFar->getKind() == Node::KSpecialSubstitution) {
- auto SSK = static_cast<SpecialSubstitution *>(SoFar)->SSK;
- switch (SSK) {
- case SpecialSubKind::string:
- case SpecialSubKind::istream:
- case SpecialSubKind::ostream:
- case SpecialSubKind::iostream:
- SoFar = make<ExpandedSpecialSubstitution>(SSK);
- if (!SoFar)
- return nullptr;
- break;
- default:
- break;
- }
+ // Expand the special substitution.
+ SoFar = make<ExpandedSpecialSubstitution>(
+ static_cast<SpecialSubstitution *>(SoFar));
+ if (!SoFar)
+ return nullptr;
}
if (consumeIf('C')) {