mirror of
https://github.com/capstone-engine/llvm-capstone.git
synced 2025-01-24 18:20:38 +00:00
[demangler] All <qualifiers> on one type should share one entry in the substitution table.
Previously, both <extended-qualifier>s and <CV-qualifiers> got their own entries. llvm-svn: 324968
This commit is contained in:
parent
246d769232
commit
94bd832518
@ -1977,6 +1977,7 @@ struct Db {
|
||||
Node *parseArrayType();
|
||||
Node *parsePointerToMemberType();
|
||||
Node *parseClassEnumType();
|
||||
Node *parseQualifiedType(bool &AppliesToFunction);
|
||||
|
||||
// FIXME: remove this when all the parse_* functions have been rewritten.
|
||||
template <const char *(*parse_fn)(const char *, const char *, Db &)>
|
||||
@ -2238,6 +2239,52 @@ Node *Db::parseClassEnumType() {
|
||||
return legacyParse<parse_name>();
|
||||
}
|
||||
|
||||
// <qualified-type> ::= <qualifiers> <type>
|
||||
// <qualifiers> ::= <extended-qualifier>* <CV-qualifiers>
|
||||
// <extended-qualifier> ::= U <source-name> [<template-args>] # vendor extended type qualifier
|
||||
Node *Db::parseQualifiedType(bool &AppliesToFunction) {
|
||||
if (consumeIf('U')) {
|
||||
StringView Qual = parseBareSourceName();
|
||||
if (Qual.empty())
|
||||
return nullptr;
|
||||
|
||||
// FIXME parse the optional <template-args> here!
|
||||
|
||||
// extension ::= U <objc-name> <objc-type> # objc-type<identifier>
|
||||
if (Qual.startsWith("objcproto")) {
|
||||
StringView ProtoSourceName = Qual.dropFront(std::strlen("objcproto"));
|
||||
StringView Proto;
|
||||
{
|
||||
SwapAndRestore<const char *> SaveFirst(First, ProtoSourceName.begin()),
|
||||
SaveLast(Last, ProtoSourceName.end());
|
||||
Proto = parseBareSourceName();
|
||||
}
|
||||
if (Proto.empty())
|
||||
return nullptr;
|
||||
Node *Child = parseQualifiedType(AppliesToFunction);
|
||||
if (Child == nullptr)
|
||||
return nullptr;
|
||||
return make<ObjCProtoName>(Child, Proto);
|
||||
}
|
||||
|
||||
Node *Child = parseQualifiedType(AppliesToFunction);
|
||||
if (Child == nullptr)
|
||||
return nullptr;
|
||||
return make<VendorExtQualType>(Child, Qual);
|
||||
}
|
||||
|
||||
Qualifiers Quals = parseCVQualifiers();
|
||||
AppliesToFunction = look() == 'F';
|
||||
Node *Ty = parseType();
|
||||
if (Ty == nullptr)
|
||||
return nullptr;
|
||||
if (Quals != QualNone) {
|
||||
return AppliesToFunction ?
|
||||
make<FunctionQualType>(Ty, Quals) : make<QualType>(Ty, Quals);
|
||||
}
|
||||
return Ty;
|
||||
}
|
||||
|
||||
// <type> ::= <builtin-type>
|
||||
// ::= <qualified-type>
|
||||
// ::= <function-type>
|
||||
@ -2265,18 +2312,10 @@ Node *Db::parseType() {
|
||||
// ::= <qualified-type>
|
||||
case 'r':
|
||||
case 'V':
|
||||
case 'K': {
|
||||
Qualifiers Q = parseCVQualifiers();
|
||||
bool AppliesToFunction = look() == 'F';
|
||||
|
||||
Node *Child = parseType();
|
||||
if (Child == nullptr)
|
||||
return nullptr;
|
||||
|
||||
if (AppliesToFunction)
|
||||
Result = make<FunctionQualType>(Child, Q);
|
||||
else
|
||||
Result = make<QualType>(Child, Q);
|
||||
case 'K':
|
||||
case 'U': {
|
||||
bool AppliesToFunction = false;
|
||||
Result = parseQualifiedType(AppliesToFunction);
|
||||
|
||||
// Itanium C++ ABI 5.1.5.3:
|
||||
// For the purposes of substitution, the CV-qualifiers and ref-qualifier
|
||||
@ -2285,39 +2324,6 @@ Node *Db::parseType() {
|
||||
return Result;
|
||||
break;
|
||||
}
|
||||
// <extended-qualifier> ::= U <source-name> [<template-args>] # vendor extended type qualifier
|
||||
case 'U': {
|
||||
// FIXME: We should fold this into the cvr qualifier parsing above. This
|
||||
// currently adds too many entries into the substitution table if multiple
|
||||
// qualifiers are present on the same type, as all the qualifiers on a type
|
||||
// should just get one entry in the substitution table.
|
||||
++First;
|
||||
StringView Qual = parseBareSourceName();
|
||||
if (Qual.empty())
|
||||
return nullptr;
|
||||
|
||||
// FIXME parse the optional <template-args> here!
|
||||
|
||||
Result = parseType();
|
||||
if (Result == nullptr)
|
||||
return nullptr;
|
||||
|
||||
// extension ::= U <objc-name> <objc-type> # objc-type<identifier>
|
||||
if (Qual.startsWith("objcproto")) {
|
||||
StringView ProtoSourceName = Qual.dropFront(std::strlen("objcproto"));
|
||||
StringView Proto;
|
||||
{
|
||||
SwapAndRestore<const char *> SaveFirst(First, ProtoSourceName.begin()),
|
||||
SaveLast(Last, ProtoSourceName.end());
|
||||
Proto = parseBareSourceName();
|
||||
}
|
||||
if (Proto.empty())
|
||||
return nullptr;
|
||||
Result = make<ObjCProtoName>(Result, Proto);
|
||||
} else
|
||||
Result = make<VendorExtQualType>(Result, Qual);
|
||||
break;
|
||||
}
|
||||
// <builtin-type> ::= v # void
|
||||
case 'v':
|
||||
++First;
|
||||
|
@ -29656,6 +29656,9 @@ const char* cases[][2] =
|
||||
{"_ZN5test73fT4IiEEDTcvT_Li1EES1_", "decltype((int)(1)) test7::fT4<int>(int)"},
|
||||
{"_ZN5test73fT6INS_1BEEEDTcvT__Li1ELi2EEES2_", "decltype((test7::B)(1, 2)) test7::fT6<test7::B>(test7::B)"},
|
||||
{"_ZNK5test81XIiE3barIiEEDTcl3fooIT_EEEv", "decltype(foo<int>()) test8::X<int>::bar<int>() const"},
|
||||
|
||||
// Multiple qualifiers on the same type should all get the same entry in the substitution table.
|
||||
{"_Z1fPU3AS1KiS0_", "f(int const AS1*, int const AS1*)"}
|
||||
};
|
||||
|
||||
const unsigned N = sizeof(cases) / sizeof(cases[0]);
|
||||
|
Loading…
x
Reference in New Issue
Block a user