forked from OSchip/llvm-project
Demangling support for class type non-type template parameter extensions.
The extensions in question are described in: https://github.com/itanium-cxx-abi/cxx-abi/issues/47 https://github.com/itanium-cxx-abi/cxx-abi/issues/63 Differential Revision: https://reviews.llvm.org/D90003
This commit is contained in:
parent
0b420d674a
commit
bec968cbb3
|
@ -82,6 +82,7 @@
|
|||
X(PostfixExpr) \
|
||||
X(ConditionalExpr) \
|
||||
X(MemberExpr) \
|
||||
X(SubobjectExpr) \
|
||||
X(EnclosingExpr) \
|
||||
X(CastExpr) \
|
||||
X(SizeofParamPackExpr) \
|
||||
|
@ -91,6 +92,7 @@
|
|||
X(PrefixExpr) \
|
||||
X(FunctionParam) \
|
||||
X(ConversionExpr) \
|
||||
X(PointerToMemberConversionExpr) \
|
||||
X(InitListExpr) \
|
||||
X(FoldExpr) \
|
||||
X(ThrowExpr) \
|
||||
|
@ -1656,6 +1658,40 @@ public:
|
|||
}
|
||||
};
|
||||
|
||||
class SubobjectExpr : public Node {
|
||||
const Node *Type;
|
||||
const Node *SubExpr;
|
||||
StringView Offset;
|
||||
NodeArray UnionSelectors;
|
||||
bool OnePastTheEnd;
|
||||
|
||||
public:
|
||||
SubobjectExpr(const Node *Type_, const Node *SubExpr_, StringView Offset_,
|
||||
NodeArray UnionSelectors_, bool OnePastTheEnd_)
|
||||
: Node(KSubobjectExpr), Type(Type_), SubExpr(SubExpr_), Offset(Offset_),
|
||||
UnionSelectors(UnionSelectors_), OnePastTheEnd(OnePastTheEnd_) {}
|
||||
|
||||
template<typename Fn> void match(Fn F) const {
|
||||
F(Type, SubExpr, Offset, UnionSelectors, OnePastTheEnd);
|
||||
}
|
||||
|
||||
void printLeft(OutputStream &S) const override {
|
||||
SubExpr->print(S);
|
||||
S += ".<";
|
||||
Type->print(S);
|
||||
S += " at offset ";
|
||||
if (Offset.empty()) {
|
||||
S += "0";
|
||||
} else if (Offset[0] == 'n') {
|
||||
S += "-";
|
||||
S += Offset.dropFront();
|
||||
} else {
|
||||
S += Offset;
|
||||
}
|
||||
S += ">";
|
||||
}
|
||||
};
|
||||
|
||||
class EnclosingExpr : public Node {
|
||||
const StringView Prefix;
|
||||
const Node *Infix;
|
||||
|
@ -1843,6 +1879,28 @@ public:
|
|||
}
|
||||
};
|
||||
|
||||
class PointerToMemberConversionExpr : public Node {
|
||||
const Node *Type;
|
||||
const Node *SubExpr;
|
||||
StringView Offset;
|
||||
|
||||
public:
|
||||
PointerToMemberConversionExpr(const Node *Type_, const Node *SubExpr_,
|
||||
StringView Offset_)
|
||||
: Node(KPointerToMemberConversionExpr), Type(Type_), SubExpr(SubExpr_),
|
||||
Offset(Offset_) {}
|
||||
|
||||
template<typename Fn> void match(Fn F) const { F(Type, SubExpr, Offset); }
|
||||
|
||||
void printLeft(OutputStream &S) const override {
|
||||
S += "(";
|
||||
Type->print(S);
|
||||
S += ")(";
|
||||
SubExpr->print(S);
|
||||
S += ")";
|
||||
}
|
||||
};
|
||||
|
||||
class InitListExpr : public Node {
|
||||
const Node *Ty;
|
||||
NodeArray Inits;
|
||||
|
@ -2437,6 +2495,8 @@ template <typename Derived, typename Alloc> struct AbstractManglingParser {
|
|||
Node *parseConversionExpr();
|
||||
Node *parseBracedExpr();
|
||||
Node *parseFoldExpr();
|
||||
Node *parsePointerToMemberConversionExpr();
|
||||
Node *parseSubobjectExpr();
|
||||
|
||||
/// Parse the <type> production.
|
||||
Node *parseType();
|
||||
|
@ -4404,6 +4464,50 @@ Node *AbstractManglingParser<Derived, Alloc>::parseFoldExpr() {
|
|||
return make<FoldExpr>(IsLeftFold, OperatorName, Pack, Init);
|
||||
}
|
||||
|
||||
// <expression> ::= mc <parameter type> <expr> [<offset number>] E
|
||||
//
|
||||
// Not yet in the spec: https://github.com/itanium-cxx-abi/cxx-abi/issues/47
|
||||
template <typename Derived, typename Alloc>
|
||||
Node *AbstractManglingParser<Derived, Alloc>::parsePointerToMemberConversionExpr() {
|
||||
Node *Ty = getDerived().parseType();
|
||||
if (!Ty)
|
||||
return nullptr;
|
||||
Node *Expr = getDerived().parseExpr();
|
||||
if (!Expr)
|
||||
return nullptr;
|
||||
StringView Offset = getDerived().parseNumber(true);
|
||||
if (!consumeIf('E'))
|
||||
return nullptr;
|
||||
return make<PointerToMemberConversionExpr>(Ty, Expr, Offset);
|
||||
}
|
||||
|
||||
// <expression> ::= so <referent type> <expr> [<offset number>] <union-selector>* [p] E
|
||||
// <union-selector> ::= _ [<number>]
|
||||
//
|
||||
// Not yet in the spec: https://github.com/itanium-cxx-abi/cxx-abi/issues/47
|
||||
template <typename Derived, typename Alloc>
|
||||
Node *AbstractManglingParser<Derived, Alloc>::parseSubobjectExpr() {
|
||||
Node *Ty = getDerived().parseType();
|
||||
if (!Ty)
|
||||
return nullptr;
|
||||
Node *Expr = getDerived().parseExpr();
|
||||
if (!Expr)
|
||||
return nullptr;
|
||||
StringView Offset = getDerived().parseNumber(true);
|
||||
size_t SelectorsBegin = Names.size();
|
||||
while (consumeIf('_')) {
|
||||
Node *Selector = make<NameType>(parseNumber());
|
||||
if (!Selector)
|
||||
return nullptr;
|
||||
Names.push_back(Selector);
|
||||
}
|
||||
bool OnePastTheEnd = consumeIf('p');
|
||||
if (!consumeIf('E'))
|
||||
return nullptr;
|
||||
return make<SubobjectExpr>(
|
||||
Ty, Expr, Offset, popTrailingNodeArray(SelectorsBegin), OnePastTheEnd);
|
||||
}
|
||||
|
||||
// <expression> ::= <unary operator-name> <expression>
|
||||
// ::= <binary operator-name> <expression> <expression>
|
||||
// ::= <ternary operator-name> <expression> <expression> <expression>
|
||||
|
@ -4661,6 +4765,9 @@ Node *AbstractManglingParser<Derived, Alloc>::parseExpr() {
|
|||
return nullptr;
|
||||
case 'm':
|
||||
switch (First[1]) {
|
||||
case 'c':
|
||||
First += 2;
|
||||
return parsePointerToMemberConversionExpr();
|
||||
case 'i':
|
||||
First += 2;
|
||||
return getDerived().parseBinaryExpr("-");
|
||||
|
@ -4808,6 +4915,9 @@ Node *AbstractManglingParser<Derived, Alloc>::parseExpr() {
|
|||
return Ex;
|
||||
return make<CastExpr>("static_cast", T, Ex);
|
||||
}
|
||||
case 'o':
|
||||
First += 2;
|
||||
return parseSubobjectExpr();
|
||||
case 'p': {
|
||||
First += 2;
|
||||
Node *Child = getDerived().parseExpr();
|
||||
|
@ -4975,6 +5085,16 @@ Node *AbstractManglingParser<Derived, Alloc>::parseSpecialName() {
|
|||
switch (look()) {
|
||||
case 'T':
|
||||
switch (look(1)) {
|
||||
// TA <template-arg> # template parameter object
|
||||
//
|
||||
// Not yet in the spec: https://github.com/itanium-cxx-abi/cxx-abi/issues/63
|
||||
case 'A': {
|
||||
First += 2;
|
||||
Node *Arg = getDerived().parseTemplateArg();
|
||||
if (Arg == nullptr)
|
||||
return nullptr;
|
||||
return make<SpecialName>("template parameter object for ", Arg);
|
||||
}
|
||||
// TV <type> # virtual table
|
||||
case 'V': {
|
||||
First += 2;
|
||||
|
|
|
@ -29800,6 +29800,21 @@ const char* cases[][2] =
|
|||
{"_ZN1XIZ1fIiEvOT_EUlS2_DpT0_E_EclIJEEEvDpT_", "void X<void f<int>(int&&)::'lambda'(int&&, auto...)>::operator()<>()"},
|
||||
{"_ZZZZN6abcdef9abcdefghi29abcdefabcdefabcdefabcefabcdef27xxxxxxxxxxxxxxxxxxxxxxxxxxxEN4absl8DurationERKNSt3__u12basic_stringIcNS4_11char_traitsIcEENS4_9allocatorIcEEEEPNS1_19yyyyyyyyyyyyyyyyyyyEENK3$_5clEvENKUlvE_clEvE6zzzzzz", "abcdef::abcdefghi::abcdefabcdefabcdefabcefabcdef::xxxxxxxxxxxxxxxxxxxxxxxxxxx(absl::Duration, std::__u::basic_string<char, std::__u::char_traits<char>, std::__u::allocator<char> > const&, abcdef::abcdefghi::abcdefabcdefabcdefabcefabcdef::yyyyyyyyyyyyyyyyyyy*)::$_5::operator()() const::'lambda'()::operator()() const::zzzzzz"},
|
||||
|
||||
// C++2a class type non-type template parameters:
|
||||
{"_Z1fIXtl1BLPi0ELi1EEEEvv", "void f<B{(int*)0, 1}>()"},
|
||||
{"_Z1fIXtl1BLPi32EEEEvv", "void f<B{(int*)32}>()"},
|
||||
{"_Z1fIXtl1BrcPiLi0EEEEvv", "void f<B{reinterpret_cast<int*>(0)}>()"},
|
||||
{"_Z1fIXtl1BadsoiL_Z6nestedE_EEEEvv", "void f<B{&(nested.<int at offset 0>)}>()"},
|
||||
{"_Z1fIXtl1BadsoiL_Z6nestedE16_0pEEEEvv", "void f<B{&(nested.<int at offset 16>)}>()"},
|
||||
{"_Z1fIXtl2BRsoiL_Z7derivedE4EEEEvv", "void f<BR{derived.<int at offset 4>}>()"},
|
||||
{"_Z1fIXtl1BcvPiplcvPcadL_Z7derivedELl16EEEEvv", "void f<B{(int*)(((char*)(&(derived))) + (16l))}>()"},
|
||||
{"_Z1fIXtl1CadsoKiL_Z7derivedE4EEEEvv", "void f<C{&(derived.<int const at offset 4>)}>()"},
|
||||
{"_Z1fIXtl1DLM7DerivedKi0ELi1EEEEvv", "void f<D{(int const Derived::*)0, 1}>()"},
|
||||
// FIXME: This is not valid pointer-to-member syntax.
|
||||
{"_Z1fIXtl1DmcM7DerivedKiadL_ZN11MoreDerived1zEEn8EEEEvv", "void f<D{(int const Derived::*)(&(MoreDerived::z))}>()"},
|
||||
{"_Z1fIXtl1Edi1nLi42EEEEvv", "void f<E{.n = 42}>()"},
|
||||
{"_ZTAXtl1StlA32_cLc104ELc101ELc108ELc108ELc111ELc32ELc119ELc111ELc114ELc108ELc100EEEE", "template parameter object for S{char [32]{(char)104, (char)101, (char)108, (char)108, (char)111, (char)32, (char)119, (char)111, (char)114, (char)108, (char)100}}"},
|
||||
|
||||
// FIXME: This is wrong; the S2_ backref should expand to OT_ and then to
|
||||
// "double&&". But we can't cope with a substitution that represents a
|
||||
// different type the node it is a substitute for.
|
||||
|
|
|
@ -82,6 +82,7 @@
|
|||
X(PostfixExpr) \
|
||||
X(ConditionalExpr) \
|
||||
X(MemberExpr) \
|
||||
X(SubobjectExpr) \
|
||||
X(EnclosingExpr) \
|
||||
X(CastExpr) \
|
||||
X(SizeofParamPackExpr) \
|
||||
|
@ -91,6 +92,7 @@
|
|||
X(PrefixExpr) \
|
||||
X(FunctionParam) \
|
||||
X(ConversionExpr) \
|
||||
X(PointerToMemberConversionExpr) \
|
||||
X(InitListExpr) \
|
||||
X(FoldExpr) \
|
||||
X(ThrowExpr) \
|
||||
|
@ -1656,6 +1658,40 @@ public:
|
|||
}
|
||||
};
|
||||
|
||||
class SubobjectExpr : public Node {
|
||||
const Node *Type;
|
||||
const Node *SubExpr;
|
||||
StringView Offset;
|
||||
NodeArray UnionSelectors;
|
||||
bool OnePastTheEnd;
|
||||
|
||||
public:
|
||||
SubobjectExpr(const Node *Type_, const Node *SubExpr_, StringView Offset_,
|
||||
NodeArray UnionSelectors_, bool OnePastTheEnd_)
|
||||
: Node(KSubobjectExpr), Type(Type_), SubExpr(SubExpr_), Offset(Offset_),
|
||||
UnionSelectors(UnionSelectors_), OnePastTheEnd(OnePastTheEnd_) {}
|
||||
|
||||
template<typename Fn> void match(Fn F) const {
|
||||
F(Type, SubExpr, Offset, UnionSelectors, OnePastTheEnd);
|
||||
}
|
||||
|
||||
void printLeft(OutputStream &S) const override {
|
||||
SubExpr->print(S);
|
||||
S += ".<";
|
||||
Type->print(S);
|
||||
S += " at offset ";
|
||||
if (Offset.empty()) {
|
||||
S += "0";
|
||||
} else if (Offset[0] == 'n') {
|
||||
S += "-";
|
||||
S += Offset.dropFront();
|
||||
} else {
|
||||
S += Offset;
|
||||
}
|
||||
S += ">";
|
||||
}
|
||||
};
|
||||
|
||||
class EnclosingExpr : public Node {
|
||||
const StringView Prefix;
|
||||
const Node *Infix;
|
||||
|
@ -1843,6 +1879,28 @@ public:
|
|||
}
|
||||
};
|
||||
|
||||
class PointerToMemberConversionExpr : public Node {
|
||||
const Node *Type;
|
||||
const Node *SubExpr;
|
||||
StringView Offset;
|
||||
|
||||
public:
|
||||
PointerToMemberConversionExpr(const Node *Type_, const Node *SubExpr_,
|
||||
StringView Offset_)
|
||||
: Node(KPointerToMemberConversionExpr), Type(Type_), SubExpr(SubExpr_),
|
||||
Offset(Offset_) {}
|
||||
|
||||
template<typename Fn> void match(Fn F) const { F(Type, SubExpr, Offset); }
|
||||
|
||||
void printLeft(OutputStream &S) const override {
|
||||
S += "(";
|
||||
Type->print(S);
|
||||
S += ")(";
|
||||
SubExpr->print(S);
|
||||
S += ")";
|
||||
}
|
||||
};
|
||||
|
||||
class InitListExpr : public Node {
|
||||
const Node *Ty;
|
||||
NodeArray Inits;
|
||||
|
@ -2437,6 +2495,8 @@ template <typename Derived, typename Alloc> struct AbstractManglingParser {
|
|||
Node *parseConversionExpr();
|
||||
Node *parseBracedExpr();
|
||||
Node *parseFoldExpr();
|
||||
Node *parsePointerToMemberConversionExpr();
|
||||
Node *parseSubobjectExpr();
|
||||
|
||||
/// Parse the <type> production.
|
||||
Node *parseType();
|
||||
|
@ -4404,6 +4464,50 @@ Node *AbstractManglingParser<Derived, Alloc>::parseFoldExpr() {
|
|||
return make<FoldExpr>(IsLeftFold, OperatorName, Pack, Init);
|
||||
}
|
||||
|
||||
// <expression> ::= mc <parameter type> <expr> [<offset number>] E
|
||||
//
|
||||
// Not yet in the spec: https://github.com/itanium-cxx-abi/cxx-abi/issues/47
|
||||
template <typename Derived, typename Alloc>
|
||||
Node *AbstractManglingParser<Derived, Alloc>::parsePointerToMemberConversionExpr() {
|
||||
Node *Ty = getDerived().parseType();
|
||||
if (!Ty)
|
||||
return nullptr;
|
||||
Node *Expr = getDerived().parseExpr();
|
||||
if (!Expr)
|
||||
return nullptr;
|
||||
StringView Offset = getDerived().parseNumber(true);
|
||||
if (!consumeIf('E'))
|
||||
return nullptr;
|
||||
return make<PointerToMemberConversionExpr>(Ty, Expr, Offset);
|
||||
}
|
||||
|
||||
// <expression> ::= so <referent type> <expr> [<offset number>] <union-selector>* [p] E
|
||||
// <union-selector> ::= _ [<number>]
|
||||
//
|
||||
// Not yet in the spec: https://github.com/itanium-cxx-abi/cxx-abi/issues/47
|
||||
template <typename Derived, typename Alloc>
|
||||
Node *AbstractManglingParser<Derived, Alloc>::parseSubobjectExpr() {
|
||||
Node *Ty = getDerived().parseType();
|
||||
if (!Ty)
|
||||
return nullptr;
|
||||
Node *Expr = getDerived().parseExpr();
|
||||
if (!Expr)
|
||||
return nullptr;
|
||||
StringView Offset = getDerived().parseNumber(true);
|
||||
size_t SelectorsBegin = Names.size();
|
||||
while (consumeIf('_')) {
|
||||
Node *Selector = make<NameType>(parseNumber());
|
||||
if (!Selector)
|
||||
return nullptr;
|
||||
Names.push_back(Selector);
|
||||
}
|
||||
bool OnePastTheEnd = consumeIf('p');
|
||||
if (!consumeIf('E'))
|
||||
return nullptr;
|
||||
return make<SubobjectExpr>(
|
||||
Ty, Expr, Offset, popTrailingNodeArray(SelectorsBegin), OnePastTheEnd);
|
||||
}
|
||||
|
||||
// <expression> ::= <unary operator-name> <expression>
|
||||
// ::= <binary operator-name> <expression> <expression>
|
||||
// ::= <ternary operator-name> <expression> <expression> <expression>
|
||||
|
@ -4661,6 +4765,9 @@ Node *AbstractManglingParser<Derived, Alloc>::parseExpr() {
|
|||
return nullptr;
|
||||
case 'm':
|
||||
switch (First[1]) {
|
||||
case 'c':
|
||||
First += 2;
|
||||
return parsePointerToMemberConversionExpr();
|
||||
case 'i':
|
||||
First += 2;
|
||||
return getDerived().parseBinaryExpr("-");
|
||||
|
@ -4808,6 +4915,9 @@ Node *AbstractManglingParser<Derived, Alloc>::parseExpr() {
|
|||
return Ex;
|
||||
return make<CastExpr>("static_cast", T, Ex);
|
||||
}
|
||||
case 'o':
|
||||
First += 2;
|
||||
return parseSubobjectExpr();
|
||||
case 'p': {
|
||||
First += 2;
|
||||
Node *Child = getDerived().parseExpr();
|
||||
|
@ -4975,6 +5085,16 @@ Node *AbstractManglingParser<Derived, Alloc>::parseSpecialName() {
|
|||
switch (look()) {
|
||||
case 'T':
|
||||
switch (look(1)) {
|
||||
// TA <template-arg> # template parameter object
|
||||
//
|
||||
// Not yet in the spec: https://github.com/itanium-cxx-abi/cxx-abi/issues/63
|
||||
case 'A': {
|
||||
First += 2;
|
||||
Node *Arg = getDerived().parseTemplateArg();
|
||||
if (Arg == nullptr)
|
||||
return nullptr;
|
||||
return make<SpecialName>("template parameter object for ", Arg);
|
||||
}
|
||||
// TV <type> # virtual table
|
||||
case 'V': {
|
||||
First += 2;
|
||||
|
|
Loading…
Reference in New Issue