demangler/gcc3+: handle vendor-specific suffix
fix bug #13720 Change-Id: I3363572b88aaa674f5ee7cf69866b9f2bbb4e84c Reviewed-on: https://review.haiku-os.org/c/haiku/+/4084 Reviewed-by: Rene Gollent <[email protected]> Reviewed-by: Alex von Gluck IV <[email protected]> Tested-by: Commit checker robot <[email protected]>
This commit is contained in:
committed by
Alex von Gluck IV
parent
8c232f164a
commit
1b0f948ea2
@@ -1,5 +1,6 @@
|
||||
/*
|
||||
* Copyright 2009-2011, Ingo Weinhold, [email protected].
|
||||
* Copyright 2021, Jerome Duval, [email protected].
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
|
||||
@@ -20,7 +21,7 @@
|
||||
#include "demangle.h"
|
||||
|
||||
|
||||
// C++ ABI: http://www.codesourcery.com/public/cxx-abi/abi.html
|
||||
// C++ ABI: https://itanium-cxx-abi.github.io/cxx-abi/abi.html
|
||||
|
||||
|
||||
//#define TRACE_GCC3_DEMANGLER
|
||||
@@ -1297,6 +1298,58 @@ private:
|
||||
};
|
||||
|
||||
|
||||
class ClonedNode : public ObjectNode {
|
||||
public:
|
||||
ClonedNode(Node* clone, Node* node)
|
||||
:
|
||||
ObjectNode(NULL),
|
||||
fNode(node),
|
||||
fCloneNode(clone)
|
||||
{
|
||||
fNode->SetParent(this);
|
||||
fCloneNode->SetParent(this);
|
||||
}
|
||||
|
||||
virtual bool GetName(NameBuffer& buffer) const
|
||||
{
|
||||
if (!fNode->GetName(buffer))
|
||||
return false;
|
||||
|
||||
buffer.Append(" [clone ");
|
||||
if (!fCloneNode->GetName(buffer))
|
||||
return false;
|
||||
buffer.Append("]");
|
||||
return true;
|
||||
}
|
||||
|
||||
virtual Node* GetUnqualifiedNode(Node* beforeNode)
|
||||
{
|
||||
return beforeNode == fCloneNode
|
||||
? fNode->GetUnqualifiedNode(beforeNode)
|
||||
: fCloneNode->GetUnqualifiedNode(beforeNode);
|
||||
}
|
||||
|
||||
virtual bool IsNoReturnValueFunction() const
|
||||
{
|
||||
return fNode->IsNoReturnValueFunction();
|
||||
}
|
||||
|
||||
virtual object_type ObjectType() const
|
||||
{
|
||||
return fNode->ObjectType();
|
||||
}
|
||||
|
||||
virtual prefix_type PrefixType() const
|
||||
{
|
||||
return PREFIX_UNKNOWN;
|
||||
}
|
||||
|
||||
private:
|
||||
Node* fNode;
|
||||
Node* fCloneNode;
|
||||
};
|
||||
|
||||
|
||||
typedef PrefixedNode DependentNameNode;
|
||||
|
||||
|
||||
@@ -1843,6 +1896,7 @@ private:
|
||||
const char*& versionSuffix,
|
||||
ObjectNode*& _node);
|
||||
|
||||
bool _ParseClone(ObjectNode*& _node);
|
||||
bool _ParseEncoding(ObjectNode*& _node);
|
||||
bool _ParseSpecialName(Node*& _node);
|
||||
bool _ParseCallOffset(bool& nonVirtual,
|
||||
@@ -2135,12 +2189,12 @@ Demangler::_Parse(const char* mangledName, const char*& versionSuffix,
|
||||
versionSuffix != NULL
|
||||
? versionSuffix - mangledName : strlen(mangledName));
|
||||
|
||||
// <mangled-name> ::= _Z <encoding>
|
||||
// <mangled-name> ::= _Z <encoding> [<clone-suffix>]*
|
||||
|
||||
if (!fInput.SkipPrefix("_Z"))
|
||||
return ERROR_NOT_MANGLED;
|
||||
|
||||
if (!_ParseEncoding(_node))
|
||||
if (!_ParseEncoding(_node) || !_ParseClone(_node))
|
||||
return fError;
|
||||
|
||||
if (fInput.CharsRemaining() != 0) {
|
||||
@@ -2152,6 +2206,34 @@ Demangler::_Parse(const char* mangledName, const char*& versionSuffix,
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
Demangler::_ParseClone(ObjectNode*& _node)
|
||||
{
|
||||
DEBUG_SCOPE("_ParseClone");
|
||||
|
||||
while (fInput.HasPrefix('.')) {
|
||||
int count = fInput.CharsRemaining();
|
||||
int i = 1;
|
||||
while (true) {
|
||||
for (; i < count && fInput[i] != '.'; i++)
|
||||
;
|
||||
if (i + 1 >= count || fInput[i + 1] < '0' || fInput[i + 1] > '9')
|
||||
break;
|
||||
i++;
|
||||
}
|
||||
if (i == 1)
|
||||
break;
|
||||
Node* clone;
|
||||
if (!_CreateNodeAndSkip(fInput.String(), i, i, clone))
|
||||
return false;
|
||||
|
||||
if (!NodeCreator<ClonedNode>(this)(clone, _node, _node))
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
Demangler::_ParseEncoding(ObjectNode*& _node)
|
||||
{
|
||||
@@ -2176,7 +2258,8 @@ Demangler::_ParseEncoding(ObjectNode*& _node)
|
||||
if (!_ParseName(name))
|
||||
return false;
|
||||
|
||||
if (fInput.CharsRemaining() == 0 || fInput.HasPrefix('E')) {
|
||||
if (fInput.CharsRemaining() == 0 || fInput.HasPrefix('E')
|
||||
|| fInput.HasPrefix('.')) {
|
||||
// <data name>
|
||||
return NodeCreator<ObjectNode>(this)(name, _node);
|
||||
}
|
||||
@@ -3225,8 +3308,9 @@ Demangler::_ParseBareFunctionType(FunctionNode* node)
|
||||
return false;
|
||||
|
||||
node->AddType(typeNode);
|
||||
} while (fInput.CharsRemaining() > 0 && fInput[0] != 'E');
|
||||
// 'E' delimits <function-type>
|
||||
} while (fInput.CharsRemaining() > 0 && fInput[0] != 'E'
|
||||
&& fInput[0] != '.');
|
||||
// 'E' und '.' delimit <function-type>
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -51,6 +51,9 @@ DemangleTest::RunGCC3PTests()
|
||||
"_ZN8BPrivate16BContainerWindow10UpdateMenuEP5BMenuNS0_17UpdateMenuContextE");
|
||||
TEST("icu_57::BreakIterator::registerInstance(icu_57::BreakIterator*, icu_57::Locale const&, UBreakIteratorType, UErrorCode&)",
|
||||
"_ZN6icu_5713BreakIterator16registerInstanceEPS0_RKNS_6LocaleE18UBreakIteratorTypeR10UErrorCode");
|
||||
TEST("void std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::_M_construct<char*>(char*, char*, std::forward_iterator_tag) [clone .isra.25]",
|
||||
"_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE12_M_constructIPcEEvT_S7_St20forward_iterator_tag.isra.25");
|
||||
TEST("foo(int) [clone .part.1.123456] [clone .constprop.777.54321]", "_Z3fooi.part.1.123456.constprop.777.54321");
|
||||
}
|
||||
#undef TEST
|
||||
|
||||
|
||||
Reference in New Issue
Block a user