[libcxxabi] r338138 - [demangler] Support for reference collapsing
Erik Pilkington via cfe-commits
cfe-commits at lists.llvm.org
Fri Jul 27 10:27:40 PDT 2018
Author: epilk
Date: Fri Jul 27 10:27:40 2018
New Revision: 338138
URL: http://llvm.org/viewvc/llvm-project?rev=338138&view=rev
Log:
[demangler] Support for reference collapsing
llvm.org/PR38323
Modified:
libcxxabi/trunk/src/cxa_demangle.cpp
libcxxabi/trunk/test/test_demangle.pass.cpp
Modified: libcxxabi/trunk/src/cxa_demangle.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxxabi/trunk/src/cxa_demangle.cpp?rev=338138&r1=338137&r2=338138&view=diff
==============================================================================
--- libcxxabi/trunk/src/cxa_demangle.cpp (original)
+++ libcxxabi/trunk/src/cxa_demangle.cpp Fri Jul 27 10:27:40 2018
@@ -25,11 +25,10 @@
#include <cstdlib>
#include <cstring>
#include <numeric>
+#include <utility>
#include <vector>
-
namespace {
-
enum : int {
demangle_unknown_error = -4,
demangle_invalid_args = -3,
@@ -55,8 +54,7 @@ public:
KEnableIfAttr,
KObjCProtoName,
KPointerType,
- KLValueReferenceType,
- KRValueReferenceType,
+ KReferenceType,
KPointerToMemberType,
KArrayType,
KFunctionType,
@@ -137,6 +135,12 @@ public:
virtual bool hasArraySlow(OutputStream &) const { return false; }
virtual bool hasFunctionSlow(OutputStream &) const { return false; }
+ // Dig through "glue" nodes like ParameterPack and ForwardTemplateReference to
+ // get at a node that actually represents some concrete syntax.
+ virtual const Node *getSyntaxNode(OutputStream &) const {
+ return this;
+ }
+
void print(OutputStream &S) const {
printLeft(S);
if (RHSComponentCache != Cache::No)
@@ -447,60 +451,56 @@ public:
}
};
-class LValueReferenceType final : public Node {
- const Node *Pointee;
-
-public:
- LValueReferenceType(Node *Pointee_)
- : Node(KLValueReferenceType, Pointee_->RHSComponentCache),
- Pointee(Pointee_) {}
-
- bool hasRHSComponentSlow(OutputStream &S) const override {
- return Pointee->hasRHSComponent(S);
- }
-
- void printLeft(OutputStream &s) const override {
- Pointee->printLeft(s);
- if (Pointee->hasArray(s))
- s += " ";
- if (Pointee->hasArray(s) || Pointee->hasFunction(s))
- s += "(&";
- else
- s += "&";
- }
- void printRight(OutputStream &s) const override {
- if (Pointee->hasArray(s) || Pointee->hasFunction(s))
- s += ")";
- Pointee->printRight(s);
- }
+enum class ReferenceKind {
+ LValue,
+ RValue,
};
-class RValueReferenceType final : public Node {
+// Represents either a LValue or an RValue reference type.
+class ReferenceType : public Node {
const Node *Pointee;
+ ReferenceKind RK;
+
+ // Dig through any refs to refs, collapsing the ReferenceTypes as we go. The
+ // rule here is rvalue ref to rvalue ref collapses to a rvalue ref, and any
+ // other combination collapses to a lvalue ref.
+ std::pair<ReferenceKind, const Node *> collapse(OutputStream &S) const {
+ auto SoFar = std::make_pair(RK, Pointee);
+ for (;;) {
+ const Node *SN = SoFar.second->getSyntaxNode(S);
+ if (SN->getKind() != KReferenceType)
+ break;
+ auto *RT = static_cast<const ReferenceType *>(SN);
+ SoFar.second = RT->Pointee;
+ SoFar.first = std::min(SoFar.first, RT->RK);
+ }
+ return SoFar;
+ }
public:
- RValueReferenceType(Node *Pointee_)
- : Node(KRValueReferenceType, Pointee_->RHSComponentCache),
- Pointee(Pointee_) {}
+ ReferenceType(Node *Pointee_, ReferenceKind RK_)
+ : Node(KReferenceType, Pointee_->RHSComponentCache),
+ Pointee(Pointee_), RK(RK_) {}
bool hasRHSComponentSlow(OutputStream &S) const override {
return Pointee->hasRHSComponent(S);
}
void printLeft(OutputStream &s) const override {
- Pointee->printLeft(s);
- if (Pointee->hasArray(s))
+ std::pair<ReferenceKind, const Node *> Collapsed = collapse(s);
+ Collapsed.second->printLeft(s);
+ if (Collapsed.second->hasArray(s))
s += " ";
- if (Pointee->hasArray(s) || Pointee->hasFunction(s))
- s += "(&&";
- else
- s += "&&";
- }
+ if (Collapsed.second->hasArray(s) || Collapsed.second->hasFunction(s))
+ s += "(";
+ s += (Collapsed.first == ReferenceKind::LValue ? "&" : "&&");
+ }
void printRight(OutputStream &s) const override {
- if (Pointee->hasArray(s) || Pointee->hasFunction(s))
+ std::pair<ReferenceKind, const Node *> Collapsed = collapse(s);
+ if (Collapsed.second->hasArray(s) || Collapsed.second->hasFunction(s))
s += ")";
- Pointee->printRight(s);
+ Collapsed.second->printRight(s);
}
};
@@ -919,6 +919,11 @@ public:
size_t Idx = S.CurrentPackIndex;
return Idx < Data.size() && Data[Idx]->hasFunction(S);
}
+ const Node *getSyntaxNode(OutputStream &S) const override {
+ initializePackExpansion(S);
+ size_t Idx = S.CurrentPackIndex;
+ return Idx < Data.size() ? Data[Idx]->getSyntaxNode(S) : this;
+ }
void printLeft(OutputStream &S) const override {
initializePackExpansion(S);
@@ -1046,6 +1051,12 @@ struct ForwardTemplateReference : Node {
SwapAndRestore<bool> SavePrinting(Printing, true);
return Ref->hasFunction(S);
}
+ const Node *getSyntaxNode(OutputStream &S) const override {
+ if (Printing)
+ return this;
+ SwapAndRestore<bool> SavePrinting(Printing, true);
+ return Ref->getSyntaxNode(S);
+ }
void printLeft(OutputStream &S) const override {
if (Printing)
@@ -3444,7 +3455,7 @@ Node *Db::parseType() {
Node *Ref = parseType();
if (Ref == nullptr)
return nullptr;
- Result = make<LValueReferenceType>(Ref);
+ Result = make<ReferenceType>(Ref, ReferenceKind::LValue);
break;
}
// ::= O <type> # r-value reference (C++11)
@@ -3453,7 +3464,7 @@ Node *Db::parseType() {
Node *Ref = parseType();
if (Ref == nullptr)
return nullptr;
- Result = make<RValueReferenceType>(Ref);
+ Result = make<ReferenceType>(Ref, ReferenceKind::RValue);
break;
}
// ::= C <type> # complex pair (C99)
Modified: libcxxabi/trunk/test/test_demangle.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxxabi/trunk/test/test_demangle.pass.cpp?rev=338138&r1=338137&r2=338138&view=diff
==============================================================================
--- libcxxabi/trunk/test/test_demangle.pass.cpp (original)
+++ libcxxabi/trunk/test/test_demangle.pass.cpp Fri Jul 27 10:27:40 2018
@@ -29749,6 +29749,10 @@ const char* cases[][2] =
{"_Z5foldlIJLi1ELi2ELi3EEEv1AIXflplT_EE", "void foldl<1, 2, 3>(A<(... + (1, 2, 3))>)"},
{"_Z5foldrIJLi1ELi2ELi3EEEv1AIXfrplT_EE", "void foldr<1, 2, 3>(A<((1, 2, 3) + ...)>)"},
{"_ZN7PartialIJLi1ELi2EEE5foldrIJLi3ELi4EEEEv1AIXplLi1EplLi2EfRplT_plLi1EplLi2EfrplT_EE", "void Partial<1, 2>::foldr<3, 4>(A<(1) + ((2) + (((3, 4) + ... + (1) + ((2) + (((3, 4) + ...))))))>)"},
+
+ // reference collapsing:
+ {"_Z1fIR1SEiOT_", "int f<S&>(S&)"},
+ {"_Z1fIJR1SS0_EEiDpOT_", "int f<S&, S>(S&, S&&)"},
};
const unsigned N = sizeof(cases) / sizeof(cases[0]);
More information about the cfe-commits
mailing list