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 2009-2011, Ingo Weinhold, [email protected].
|
||||||
|
* Copyright 2021, Jerome Duval, [email protected].
|
||||||
* Distributed under the terms of the MIT License.
|
* Distributed under the terms of the MIT License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@@ -20,7 +21,7 @@
|
|||||||
#include "demangle.h"
|
#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
|
//#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;
|
typedef PrefixedNode DependentNameNode;
|
||||||
|
|
||||||
|
|
||||||
@@ -1843,6 +1896,7 @@ private:
|
|||||||
const char*& versionSuffix,
|
const char*& versionSuffix,
|
||||||
ObjectNode*& _node);
|
ObjectNode*& _node);
|
||||||
|
|
||||||
|
bool _ParseClone(ObjectNode*& _node);
|
||||||
bool _ParseEncoding(ObjectNode*& _node);
|
bool _ParseEncoding(ObjectNode*& _node);
|
||||||
bool _ParseSpecialName(Node*& _node);
|
bool _ParseSpecialName(Node*& _node);
|
||||||
bool _ParseCallOffset(bool& nonVirtual,
|
bool _ParseCallOffset(bool& nonVirtual,
|
||||||
@@ -2135,12 +2189,12 @@ Demangler::_Parse(const char* mangledName, const char*& versionSuffix,
|
|||||||
versionSuffix != NULL
|
versionSuffix != NULL
|
||||||
? versionSuffix - mangledName : strlen(mangledName));
|
? versionSuffix - mangledName : strlen(mangledName));
|
||||||
|
|
||||||
// <mangled-name> ::= _Z <encoding>
|
// <mangled-name> ::= _Z <encoding> [<clone-suffix>]*
|
||||||
|
|
||||||
if (!fInput.SkipPrefix("_Z"))
|
if (!fInput.SkipPrefix("_Z"))
|
||||||
return ERROR_NOT_MANGLED;
|
return ERROR_NOT_MANGLED;
|
||||||
|
|
||||||
if (!_ParseEncoding(_node))
|
if (!_ParseEncoding(_node) || !_ParseClone(_node))
|
||||||
return fError;
|
return fError;
|
||||||
|
|
||||||
if (fInput.CharsRemaining() != 0) {
|
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
|
bool
|
||||||
Demangler::_ParseEncoding(ObjectNode*& _node)
|
Demangler::_ParseEncoding(ObjectNode*& _node)
|
||||||
{
|
{
|
||||||
@@ -2176,7 +2258,8 @@ Demangler::_ParseEncoding(ObjectNode*& _node)
|
|||||||
if (!_ParseName(name))
|
if (!_ParseName(name))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (fInput.CharsRemaining() == 0 || fInput.HasPrefix('E')) {
|
if (fInput.CharsRemaining() == 0 || fInput.HasPrefix('E')
|
||||||
|
|| fInput.HasPrefix('.')) {
|
||||||
// <data name>
|
// <data name>
|
||||||
return NodeCreator<ObjectNode>(this)(name, _node);
|
return NodeCreator<ObjectNode>(this)(name, _node);
|
||||||
}
|
}
|
||||||
@@ -3225,8 +3308,9 @@ Demangler::_ParseBareFunctionType(FunctionNode* node)
|
|||||||
return false;
|
return false;
|
||||||
|
|
||||||
node->AddType(typeNode);
|
node->AddType(typeNode);
|
||||||
} while (fInput.CharsRemaining() > 0 && fInput[0] != 'E');
|
} while (fInput.CharsRemaining() > 0 && fInput[0] != 'E'
|
||||||
// 'E' delimits <function-type>
|
&& fInput[0] != '.');
|
||||||
|
// 'E' und '.' delimit <function-type>
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -51,6 +51,9 @@ DemangleTest::RunGCC3PTests()
|
|||||||
"_ZN8BPrivate16BContainerWindow10UpdateMenuEP5BMenuNS0_17UpdateMenuContextE");
|
"_ZN8BPrivate16BContainerWindow10UpdateMenuEP5BMenuNS0_17UpdateMenuContextE");
|
||||||
TEST("icu_57::BreakIterator::registerInstance(icu_57::BreakIterator*, icu_57::Locale const&, UBreakIteratorType, UErrorCode&)",
|
TEST("icu_57::BreakIterator::registerInstance(icu_57::BreakIterator*, icu_57::Locale const&, UBreakIteratorType, UErrorCode&)",
|
||||||
"_ZN6icu_5713BreakIterator16registerInstanceEPS0_RKNS_6LocaleE18UBreakIteratorTypeR10UErrorCode");
|
"_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
|
#undef TEST
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user