1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-10-19 02:52:53 +02:00

[demangler] Support for reference collapsing

llvm.org/PR38323

llvm-svn: 338138
This commit is contained in:
Erik Pilkington 2018-07-27 17:27:40 +00:00
parent 45a1f88748
commit cae6be968e

View File

@ -22,12 +22,10 @@
#include <cstdlib>
#include <cstring>
#include <numeric>
#include <utility>
#include <vector>
namespace {
// Base class of all AST nodes. The AST is built by the parser, then is
// traversed by the printLeft/Right functions to produce a demangled string.
class Node {
@ -45,8 +43,7 @@ public:
KEnableIfAttr,
KObjCProtoName,
KPointerType,
KLValueReferenceType,
KRValueReferenceType,
KReferenceType,
KPointerToMemberType,
KArrayType,
KFunctionType,
@ -127,6 +124,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)
@ -437,60 +440,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);
}
};
@ -909,6 +908,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);
@ -1036,6 +1040,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)
@ -3434,7 +3444,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)
@ -3443,7 +3453,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)