mirror of
https://github.com/capstone-engine/llvm-capstone.git
synced 2025-04-01 12:43:47 +00:00
I'd no sooner made the last commit when Matthew Dempsky sent me another test case that led me to yet another closely related test case that the current design could not handle. I've now changed the way forward references are handled completely. It wasn't that much code to change. The demangler, when confronted with a forward reference to a template parameter, now parses things twice. During the second parse, all forward references are remembered from the first parse. Test suite updated with new case.
llvm-svn: 184672
This commit is contained in:
parent
78428401e9
commit
60c16eb7f5
@ -547,7 +547,7 @@ parse_template_param(const char* first, const char* last, C& db)
|
||||
}
|
||||
else
|
||||
{
|
||||
db.names.push_back("`T_");
|
||||
db.names.push_back("T_");
|
||||
first += 2;
|
||||
db.fix_forward_references = true;
|
||||
}
|
||||
@ -572,7 +572,7 @@ parse_template_param(const char* first, const char* last, C& db)
|
||||
}
|
||||
else
|
||||
{
|
||||
db.names.push_back("`" + typename C::String(first, t+1));
|
||||
db.names.push_back(typename C::String(first, t+1));
|
||||
first = t+1;
|
||||
db.fix_forward_references = true;
|
||||
}
|
||||
@ -4425,51 +4425,6 @@ demangle(const char* first, const char* last, C& db, int& status)
|
||||
}
|
||||
if (status == success && db.names.empty())
|
||||
status = invalid_mangled_name;
|
||||
if (status == success && db.fix_forward_references)
|
||||
{
|
||||
auto nm = db.names.back().move_full();
|
||||
db.names.pop_back();
|
||||
size_t p = nm.size();
|
||||
while (p != 0)
|
||||
{
|
||||
if (nm[--p] == '`')
|
||||
{
|
||||
size_t k0 = db.names.size();
|
||||
const char* t = parse_template_param(&nm[p+1], &nm[nm.size()], db);
|
||||
size_t k1 = db.names.size();
|
||||
if (t == &nm[p+1])
|
||||
{
|
||||
status = invalid_mangled_name;
|
||||
return;
|
||||
}
|
||||
if (k1 == k0)
|
||||
{
|
||||
nm.erase(p, static_cast<std::size_t>(t - &nm[p]));
|
||||
}
|
||||
else
|
||||
{
|
||||
if (db.names[k0].first.front() == '`')
|
||||
{
|
||||
status = invalid_mangled_name;
|
||||
return;
|
||||
}
|
||||
size_t p2 = static_cast<size_t>(t - &nm[p]);
|
||||
size_t s = db.names[k0].size();
|
||||
nm.replace(p, p2, db.names[k0].move_full());
|
||||
p2 = p + s;
|
||||
for (size_t k = k0+1; k < k1; ++k)
|
||||
{
|
||||
s = db.names[k].size() + 2;
|
||||
nm.insert(p2, ", " + db.names[k].move_full());
|
||||
p2 += s;
|
||||
}
|
||||
for (; k1 > k0; --k1)
|
||||
db.names.pop_back();
|
||||
}
|
||||
}
|
||||
}
|
||||
db.names.push_back(std::move(nm));
|
||||
}
|
||||
}
|
||||
|
||||
template <std::size_t N>
|
||||
@ -4682,8 +4637,20 @@ __cxa_demangle(const char* mangled_name, char* buf, size_t* n, int* status)
|
||||
db.fix_forward_references = false;
|
||||
db.try_to_parse_template_args = true;
|
||||
int internal_status = success;
|
||||
demangle(mangled_name, mangled_name + std::strlen(mangled_name), db,
|
||||
size_t len = std::strlen(mangled_name);
|
||||
demangle(mangled_name, mangled_name + len, db,
|
||||
internal_status);
|
||||
if (internal_status == success && db.fix_forward_references &&
|
||||
!db.template_param.empty() && !db.template_param.front().empty())
|
||||
{
|
||||
db.fix_forward_references = false;
|
||||
db.tag_templates = false;
|
||||
db.names.clear();
|
||||
db.subs.clear();
|
||||
demangle(mangled_name, mangled_name + len, db, internal_status);
|
||||
if (db.fix_forward_references)
|
||||
internal_status = invalid_mangled_name;
|
||||
}
|
||||
if (internal_status == success)
|
||||
{
|
||||
size_t sz = db.names.back().size() + 1;
|
||||
|
@ -29582,6 +29582,7 @@ const char* cases[][2] =
|
||||
{"_Z1rM1GFivEMS_KFivES_M1HFivES1_4whatIKS_E5what2IS8_ES3_", "r(int (G::*)(), int (G::*)() const, G, int (H::*)(), int (G::*)(), what<G const>, what2<G const>, int (G::*)() const)"},
|
||||
{"_Z1fPU11objcproto1A11objc_object", "f(id<A>)"},
|
||||
{"_Z1fPKU11objcproto1A7NSArray", "f(NSArray<A> const*)"},
|
||||
{"_ZNK1AIJ1Z1Y1XEEcv1BIJDpPT_EEIJS2_S1_S0_EEEv", "A<Z, Y, X>::operator B<X*, Y*, Z*><X, Y, Z>() const"},
|
||||
};
|
||||
|
||||
const unsigned N = sizeof(cases) / sizeof(cases[0]);
|
||||
@ -29592,7 +29593,6 @@ const char* invalid_cases[] =
|
||||
"Agentt",
|
||||
"NSoERj5E=Y1[uM:ga",
|
||||
"Aon_PmKVPDk7?fg4XP5smMUL6;<WsI_mgbf23cCgsHbT<l8EE\0uVRkNOoXDrgdA4[8IU>Vl<>IL8ayHpiVDDDXTY;^o9;i",
|
||||
"_ZN8Blizza`d6Memory12voidp_returncvPT_IcEEv",
|
||||
"_ZNSt16allocator_traitsISaIN4llvm3sys2fs18directory_iteratorEEE9constructIS3_IS3_EEEDTcl12_S_constructfp_fp0_spcl7forwardIT0_Efp1_EEERS4_PT_DpOS7_",
|
||||
};
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user