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:
parent
45a1f88748
commit
cae6be968e
@ -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)
|
||||
|
Loading…
Reference in New Issue
Block a user