forked from qt-creator/qt-creator
Debugger: Refactor name demangler.
So far, we converted the mangled to the demangled representation on the fly while parsing. Because some demangled strings look different depending on higher-level context, awkward string manipulations were then necessary at some later point. The new solution is much more easily maintainable, creating a tree with a node for every rule in the grammar first and converting the complete tree to the demangled string later. Change-Id: I59088df259611d7cd78af47b81b6a21d628a787f Reviewed-by: Christian Kandeler <christian.kandeler@nokia.com>
This commit is contained in:
@@ -47,7 +47,6 @@ HEADERS += \
|
|||||||
memoryagent.h \
|
memoryagent.h \
|
||||||
moduleshandler.h \
|
moduleshandler.h \
|
||||||
moduleswindow.h \
|
moduleswindow.h \
|
||||||
name_demangler.h \
|
|
||||||
outputcollector.h \
|
outputcollector.h \
|
||||||
procinterrupt.h \
|
procinterrupt.h \
|
||||||
registerhandler.h \
|
registerhandler.h \
|
||||||
@@ -103,7 +102,6 @@ SOURCES += \
|
|||||||
memoryagent.cpp \
|
memoryagent.cpp \
|
||||||
moduleshandler.cpp \
|
moduleshandler.cpp \
|
||||||
moduleswindow.cpp \
|
moduleswindow.cpp \
|
||||||
name_demangler.cpp \
|
|
||||||
outputcollector.cpp \
|
outputcollector.cpp \
|
||||||
procinterrupt.cpp \
|
procinterrupt.cpp \
|
||||||
registerhandler.cpp \
|
registerhandler.cpp \
|
||||||
@@ -162,5 +160,6 @@ include(script/script.pri)
|
|||||||
include(pdb/pdb.pri)
|
include(pdb/pdb.pri)
|
||||||
include(lldb/lldbhost.pri)
|
include(lldb/lldbhost.pri)
|
||||||
include(qml/qml.pri)
|
include(qml/qml.pri)
|
||||||
|
include(namedemangler/namedemangler.pri)
|
||||||
|
|
||||||
include(shared/shared.pri)
|
include(shared/shared.pri)
|
||||||
|
|||||||
@@ -92,8 +92,6 @@ QtcPlugin {
|
|||||||
"moduleshandler.h",
|
"moduleshandler.h",
|
||||||
"moduleswindow.cpp",
|
"moduleswindow.cpp",
|
||||||
"moduleswindow.h",
|
"moduleswindow.h",
|
||||||
"name_demangler.cpp",
|
|
||||||
"name_demangler.h",
|
|
||||||
"outputcollector.cpp",
|
"outputcollector.cpp",
|
||||||
"outputcollector.h",
|
"outputcollector.h",
|
||||||
"procinterrupt.cpp",
|
"procinterrupt.cpp",
|
||||||
@@ -262,7 +260,12 @@ QtcPlugin {
|
|||||||
"lldb/ipcenginehost.cpp",
|
"lldb/ipcenginehost.cpp",
|
||||||
"lldb/ipcenginehost.h",
|
"lldb/ipcenginehost.h",
|
||||||
"lldb/lldbenginehost.cpp",
|
"lldb/lldbenginehost.cpp",
|
||||||
"lldb/lldbenginehost.h"
|
"lldb/lldbenginehost.h",
|
||||||
|
"namedemangler/namedemangler.cpp",
|
||||||
|
"namedemangler/namedemangler.h",
|
||||||
|
"namedemangler/parsetreenodes.cpp",
|
||||||
|
"namedemangler/parsetreenodes.h",
|
||||||
|
"namedemangler/demanglerexceptions.h"
|
||||||
]
|
]
|
||||||
|
|
||||||
Group {
|
Group {
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
84
src/plugins/debugger/namedemangler/demanglerexceptions.h
Normal file
84
src/plugins/debugger/namedemangler/demanglerexceptions.h
Normal file
@@ -0,0 +1,84 @@
|
|||||||
|
/**************************************************************************
|
||||||
|
**
|
||||||
|
** This file is part of Qt Creator
|
||||||
|
**
|
||||||
|
** Copyright (c) 2012 Nokia Corporation and/or its subsidiary(-ies).
|
||||||
|
**
|
||||||
|
** Contact: Nokia Corporation (qt-info@nokia.com)
|
||||||
|
**
|
||||||
|
**
|
||||||
|
** GNU Lesser General Public License Usage
|
||||||
|
**
|
||||||
|
** This file may be used under the terms of the GNU Lesser General Public
|
||||||
|
** License version 2.1 as published by the Free Software Foundation and
|
||||||
|
** appearing in the file LICENSE.LGPL included in the packaging of this file.
|
||||||
|
** Please review the following information to ensure the GNU Lesser General
|
||||||
|
** Public License version 2.1 requirements will be met:
|
||||||
|
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||||
|
**
|
||||||
|
** In addition, as a special exception, Nokia gives you certain additional
|
||||||
|
** rights. These rights are described in the Nokia Qt LGPL Exception
|
||||||
|
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||||
|
**
|
||||||
|
** Other Usage
|
||||||
|
**
|
||||||
|
** Alternatively, this file may be used in accordance with the terms and
|
||||||
|
** conditions contained in a signed written agreement between you and Nokia.
|
||||||
|
**
|
||||||
|
** If you have questions regarding the use of this file, please contact
|
||||||
|
** Nokia at qt-info@nokia.com.
|
||||||
|
**
|
||||||
|
**************************************************************************/
|
||||||
|
#ifndef DEMANGLEREXCEPTIONS_H
|
||||||
|
#define DEMANGLEREXCEPTIONS_H
|
||||||
|
|
||||||
|
#include <QtGlobal>
|
||||||
|
#include <QString>
|
||||||
|
|
||||||
|
namespace Debugger {
|
||||||
|
namespace Internal {
|
||||||
|
|
||||||
|
class ParseTreeNode;
|
||||||
|
|
||||||
|
class ParseException
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ParseException(const QString &error) : error(error) {}
|
||||||
|
|
||||||
|
const QString error;
|
||||||
|
};
|
||||||
|
|
||||||
|
class InternalDemanglerException
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
InternalDemanglerException(const QString &func, const QString &file, int line)
|
||||||
|
: func(func), file(file), line(line) {}
|
||||||
|
|
||||||
|
QString func;
|
||||||
|
QString file;
|
||||||
|
int line;
|
||||||
|
};
|
||||||
|
|
||||||
|
#define DEMANGLER_ASSERT(cond) \
|
||||||
|
do { \
|
||||||
|
if (!cond) { \
|
||||||
|
throw InternalDemanglerException(Q_FUNC_INFO, __FILE__, __LINE__); \
|
||||||
|
} \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
template <typename T> T *demanglerCast(ParseTreeNode *node, const QString &func,
|
||||||
|
const QString &file, int line)
|
||||||
|
{
|
||||||
|
T * const out = dynamic_cast<T *>(node);
|
||||||
|
if (!out)
|
||||||
|
throw InternalDemanglerException(func, file, line);
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define DEMANGLER_CAST(type, input) demanglerCast<type>(input, QLatin1String(Q_FUNC_INFO), \
|
||||||
|
QLatin1String(__FILE__), __LINE__)
|
||||||
|
|
||||||
|
} // namespace Internal
|
||||||
|
} // namespace Debugger
|
||||||
|
|
||||||
|
#endif // DEMANGLEREXCEPTIONS_H
|
||||||
1751
src/plugins/debugger/namedemangler/namedemangler.cpp
Normal file
1751
src/plugins/debugger/namedemangler/namedemangler.cpp
Normal file
File diff suppressed because it is too large
Load Diff
8
src/plugins/debugger/namedemangler/namedemangler.pri
Normal file
8
src/plugins/debugger/namedemangler/namedemangler.pri
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
HEADERS += \
|
||||||
|
$$PWD/namedemangler.h \
|
||||||
|
$$PWD/parsetreenodes.h \
|
||||||
|
namedemangler/demanglerexceptions.h
|
||||||
|
|
||||||
|
SOURCES += \
|
||||||
|
$$PWD/namedemangler.cpp \
|
||||||
|
$$PWD/parsetreenodes.cpp
|
||||||
963
src/plugins/debugger/namedemangler/parsetreenodes.cpp
Normal file
963
src/plugins/debugger/namedemangler/parsetreenodes.cpp
Normal file
@@ -0,0 +1,963 @@
|
|||||||
|
/**************************************************************************
|
||||||
|
**
|
||||||
|
** This file is part of Qt Creator
|
||||||
|
**
|
||||||
|
** Copyright (c) 2012 Nokia Corporation and/or its subsidiary(-ies).
|
||||||
|
**
|
||||||
|
** Contact: Nokia Corporation (qt-info@nokia.com)
|
||||||
|
**
|
||||||
|
**
|
||||||
|
** GNU Lesser General Public License Usage
|
||||||
|
**
|
||||||
|
** This file may be used under the terms of the GNU Lesser General Public
|
||||||
|
** License version 2.1 as published by the Free Software Foundation and
|
||||||
|
** appearing in the file LICENSE.LGPL included in the packaging of this file.
|
||||||
|
** Please review the following information to ensure the GNU Lesser General
|
||||||
|
** Public License version 2.1 requirements will be met:
|
||||||
|
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||||
|
**
|
||||||
|
** In addition, as a special exception, Nokia gives you certain additional
|
||||||
|
** rights. These rights are described in the Nokia Qt LGPL Exception
|
||||||
|
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||||
|
**
|
||||||
|
** Other Usage
|
||||||
|
**
|
||||||
|
** Alternatively, this file may be used in accordance with the terms and
|
||||||
|
** conditions contained in a signed written agreement between you and Nokia.
|
||||||
|
**
|
||||||
|
** If you have questions regarding the use of this file, please contact
|
||||||
|
** Nokia at qt-info@nokia.com.
|
||||||
|
**
|
||||||
|
**************************************************************************/
|
||||||
|
#include "parsetreenodes.h"
|
||||||
|
|
||||||
|
#include "demanglerexceptions.h"
|
||||||
|
|
||||||
|
#include <cstring>
|
||||||
|
|
||||||
|
#define MY_CHILD_AT(index) CHILD_AT(this, index)
|
||||||
|
#define CHILD_TO_BYTEARRAY(index) CHILD_AT(this, index)->toByteArray()
|
||||||
|
|
||||||
|
namespace Debugger {
|
||||||
|
namespace Internal {
|
||||||
|
|
||||||
|
ParseTreeNode::~ParseTreeNode()
|
||||||
|
{
|
||||||
|
qDeleteAll(m_children);
|
||||||
|
}
|
||||||
|
|
||||||
|
ParseTreeNode *ParseTreeNode::childAt(int i, const QString &func, const QString &file,
|
||||||
|
int line) const
|
||||||
|
{
|
||||||
|
if (i < 0 || i >= m_children.count())
|
||||||
|
throw InternalDemanglerException(func, file, line);
|
||||||
|
return m_children.at(i);
|
||||||
|
}
|
||||||
|
|
||||||
|
QByteArray ParseTreeNode::pasteAllChildren() const
|
||||||
|
{
|
||||||
|
QByteArray repr;
|
||||||
|
foreach (const ParseTreeNode * const node, m_children)
|
||||||
|
repr += node->toByteArray();
|
||||||
|
return repr;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool ArrayTypeNode::mangledRepresentationStartsWith(char c)
|
||||||
|
{
|
||||||
|
return c == 'A';
|
||||||
|
}
|
||||||
|
|
||||||
|
QByteArray ArrayTypeNode::toByteArray() const
|
||||||
|
{
|
||||||
|
return CHILD_TO_BYTEARRAY(1) + '[' + CHILD_TO_BYTEARRAY(0) + ']';
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool BareFunctionTypeNode::mangledRepresentationStartsWith(char c)
|
||||||
|
{
|
||||||
|
return TypeNode::mangledRepresentationStartsWith(c);
|
||||||
|
}
|
||||||
|
|
||||||
|
QByteArray BareFunctionTypeNode::toByteArray() const
|
||||||
|
{
|
||||||
|
// This is only the parameter list, including parentheses. Where the return type is placed
|
||||||
|
// must be decided at a higher level.
|
||||||
|
QByteArray repr = "(";
|
||||||
|
for (int i = m_hasReturnType ? 1 : 0; i < childCount(); ++i) {
|
||||||
|
const QByteArray paramRepr = CHILD_TO_BYTEARRAY(i);
|
||||||
|
if (paramRepr != "void")
|
||||||
|
repr += paramRepr;
|
||||||
|
if (i < childCount() - 1)
|
||||||
|
repr += ", ";
|
||||||
|
}
|
||||||
|
return repr += ')';
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool BuiltinTypeNode::mangledRepresentationStartsWith(char c)
|
||||||
|
{
|
||||||
|
return strchr("vwbcahstijlmxynofgedzDu", c);
|
||||||
|
}
|
||||||
|
|
||||||
|
QByteArray BuiltinTypeNode::toByteArray() const
|
||||||
|
{
|
||||||
|
return CHILD_TO_BYTEARRAY(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool CallOffsetNode::mangledRepresentationStartsWith(char c)
|
||||||
|
{
|
||||||
|
return c == 'h' || c == 'v';
|
||||||
|
}
|
||||||
|
|
||||||
|
QByteArray CallOffsetNode::toByteArray() const
|
||||||
|
{
|
||||||
|
return CHILD_TO_BYTEARRAY(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool ClassEnumTypeNode::mangledRepresentationStartsWith(char c)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* The first set of <class-enum-type> is much smaller than
|
||||||
|
* the grammar claims.
|
||||||
|
* firstSetClassEnumType = firstSetName;
|
||||||
|
*/
|
||||||
|
return NonNegativeNumberNode::mangledRepresentationStartsWith(c)
|
||||||
|
|| c == 'N' || c == 'D' || c == 'Z';
|
||||||
|
}
|
||||||
|
|
||||||
|
QByteArray ClassEnumTypeNode::toByteArray() const
|
||||||
|
{
|
||||||
|
return CHILD_TO_BYTEARRAY(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool DiscriminatorNode::mangledRepresentationStartsWith(char c)
|
||||||
|
{
|
||||||
|
return c == '_';
|
||||||
|
}
|
||||||
|
|
||||||
|
QByteArray DiscriminatorNode::toByteArray() const
|
||||||
|
{
|
||||||
|
return CHILD_TO_BYTEARRAY(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool CtorDtorNameNode::mangledRepresentationStartsWith(char c)
|
||||||
|
{
|
||||||
|
return c == 'C' || c == 'D';
|
||||||
|
}
|
||||||
|
|
||||||
|
QByteArray CtorDtorNameNode::toByteArray() const
|
||||||
|
{
|
||||||
|
QByteArray repr = m_representation;
|
||||||
|
const int templateArgStart = repr.indexOf('<');
|
||||||
|
if (templateArgStart != -1)
|
||||||
|
repr.truncate(templateArgStart);
|
||||||
|
const int prefixEnd = repr.lastIndexOf("::");
|
||||||
|
if (prefixEnd != -1)
|
||||||
|
repr.remove(0, prefixEnd + 2);
|
||||||
|
if (m_isDestructor)
|
||||||
|
repr.prepend('~');
|
||||||
|
return repr;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool CvQualifiersNode::mangledRepresentationStartsWith(char c)
|
||||||
|
{
|
||||||
|
return c == 'K' || c == 'V' || c == 'r';
|
||||||
|
}
|
||||||
|
|
||||||
|
QByteArray CvQualifiersNode::toByteArray() const
|
||||||
|
{
|
||||||
|
QByteArray repr;
|
||||||
|
if (m_hasConst)
|
||||||
|
repr = "const";
|
||||||
|
if (m_hasVolatile) {
|
||||||
|
if (m_hasConst)
|
||||||
|
repr +=' ';
|
||||||
|
repr += "volatile";
|
||||||
|
}
|
||||||
|
return repr;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool EncodingNode::mangledRepresentationStartsWith(char c)
|
||||||
|
{
|
||||||
|
return NameNode::mangledRepresentationStartsWith(c)
|
||||||
|
|| SpecialNameNode::mangledRepresentationStartsWith(c);
|
||||||
|
}
|
||||||
|
|
||||||
|
QByteArray EncodingNode::toByteArray() const
|
||||||
|
{
|
||||||
|
if (childCount() == 1)
|
||||||
|
return CHILD_TO_BYTEARRAY(0);
|
||||||
|
|
||||||
|
const ParseTreeNode * const nameNode = MY_CHILD_AT(0);
|
||||||
|
const NestedNameNode * const nestedNameNode
|
||||||
|
= dynamic_cast<NestedNameNode *>(CHILD_AT(nameNode, 0));
|
||||||
|
const CvQualifiersNode * const cvQualifiersNode = nestedNameNode
|
||||||
|
? dynamic_cast<CvQualifiersNode *>(CHILD_AT(nestedNameNode, 0)) : 0;
|
||||||
|
|
||||||
|
QByteArray repr;
|
||||||
|
const BareFunctionTypeNode * const funcNode
|
||||||
|
= DEMANGLER_CAST(BareFunctionTypeNode, MY_CHILD_AT(1));
|
||||||
|
if (funcNode->m_hasReturnType)
|
||||||
|
repr = CHILD_AT(funcNode, 0)->toByteArray() + ' ';
|
||||||
|
if (cvQualifiersNode) {
|
||||||
|
return repr + CHILD_AT(nestedNameNode, 1)->toByteArray() + funcNode->toByteArray() + ' '
|
||||||
|
+ cvQualifiersNode->toByteArray();
|
||||||
|
}
|
||||||
|
return repr + nameNode->toByteArray() + funcNode->toByteArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool ExpressionNode::mangledRepresentationStartsWith(char c)
|
||||||
|
{
|
||||||
|
return OperatorNameNode::mangledRepresentationStartsWith(c)
|
||||||
|
|| TemplateParamNode::mangledRepresentationStartsWith(c)
|
||||||
|
/* || FunctionParamNode::mangledRepresentationStartsWith(c) */
|
||||||
|
|| ExprPrimaryNode::mangledRepresentationStartsWith(c)
|
||||||
|
|| c == 'c' || c == 's' || c == 'a';
|
||||||
|
}
|
||||||
|
|
||||||
|
QByteArray ExpressionNode::toByteArray() const
|
||||||
|
{
|
||||||
|
QByteArray repr;
|
||||||
|
|
||||||
|
switch (m_type) {
|
||||||
|
case ConversionType:
|
||||||
|
repr = CHILD_TO_BYTEARRAY(0) + '(';
|
||||||
|
for (int i = 1; i < childCount(); ++i)
|
||||||
|
repr += CHILD_TO_BYTEARRAY(i);
|
||||||
|
repr += ')';
|
||||||
|
break;
|
||||||
|
case SizeofType:
|
||||||
|
repr = "sizeof(" + CHILD_TO_BYTEARRAY(0) + ')';
|
||||||
|
break;
|
||||||
|
case AlignofType:
|
||||||
|
repr = "alignof(" + CHILD_TO_BYTEARRAY(0) + ')';
|
||||||
|
break;
|
||||||
|
case ParameterPackSizeType:
|
||||||
|
repr = CHILD_TO_BYTEARRAY(0); // TODO: What does this look like?
|
||||||
|
case OperatorType: {
|
||||||
|
const OperatorNameNode * const opNode = DEMANGLER_CAST(OperatorNameNode, MY_CHILD_AT(0));
|
||||||
|
switch (opNode->m_type) {
|
||||||
|
case OperatorNameNode::CallType:
|
||||||
|
repr = CHILD_TO_BYTEARRAY(1) + opNode->toByteArray();
|
||||||
|
break;
|
||||||
|
case OperatorNameNode::SizeofExprType: case OperatorNameNode::AlignofExprType:
|
||||||
|
repr = opNode->toByteArray() + '(' + CHILD_TO_BYTEARRAY(1) + ')';
|
||||||
|
break;
|
||||||
|
case OperatorNameNode::ArrayNewType:
|
||||||
|
repr = "new " + CHILD_TO_BYTEARRAY(1) + '[' + CHILD_TO_BYTEARRAY(2) + ']';
|
||||||
|
break;
|
||||||
|
case OperatorNameNode::IndexType:
|
||||||
|
repr = CHILD_TO_BYTEARRAY(1) + '[' + CHILD_TO_BYTEARRAY(2) + ']';
|
||||||
|
break;
|
||||||
|
case OperatorNameNode::TernaryType:
|
||||||
|
repr = CHILD_TO_BYTEARRAY(1) + " ? " + CHILD_TO_BYTEARRAY(2) + " : " + CHILD_TO_BYTEARRAY(3);
|
||||||
|
break;
|
||||||
|
case OperatorNameNode::ArrowStarType: case OperatorNameNode::ArrowType:
|
||||||
|
repr = CHILD_TO_BYTEARRAY(1) + opNode->toByteArray() + CHILD_TO_BYTEARRAY(2);
|
||||||
|
break;
|
||||||
|
case OperatorNameNode::BinaryPlusType:
|
||||||
|
case OperatorNameNode::BinaryMinusType:
|
||||||
|
case OperatorNameNode::MultType:
|
||||||
|
case OperatorNameNode::DivType:
|
||||||
|
case OperatorNameNode::ModuloType:
|
||||||
|
case OperatorNameNode::BitwiseAndType:
|
||||||
|
case OperatorNameNode::BitwiseOrType:
|
||||||
|
case OperatorNameNode::XorType:
|
||||||
|
case OperatorNameNode::AssignType:
|
||||||
|
case OperatorNameNode::IncrementAndAssignType:
|
||||||
|
case OperatorNameNode::DecrementAndAssignType:
|
||||||
|
case OperatorNameNode::MultAndAssignType:
|
||||||
|
case OperatorNameNode::DivAndAssignType:
|
||||||
|
case OperatorNameNode::ModuloAndAssignType:
|
||||||
|
case OperatorNameNode::BitwiseAndAndAssignType:
|
||||||
|
case OperatorNameNode::BitwiseOrAndAssignType:
|
||||||
|
case OperatorNameNode::XorAndAssignType:
|
||||||
|
case OperatorNameNode::LeftShiftType:
|
||||||
|
case OperatorNameNode::RightShiftType:
|
||||||
|
case OperatorNameNode::LeftShiftAndAssignType:
|
||||||
|
case OperatorNameNode::RightShiftAndAssignType:
|
||||||
|
case OperatorNameNode::EqualsType:
|
||||||
|
case OperatorNameNode::NotEqualsType:
|
||||||
|
case OperatorNameNode::LessType:
|
||||||
|
case OperatorNameNode::GreaterType:
|
||||||
|
case OperatorNameNode::LessEqualType:
|
||||||
|
case OperatorNameNode::GreaterEqualType:
|
||||||
|
case OperatorNameNode::LogicalAndType:
|
||||||
|
case OperatorNameNode::LogicalOrType:
|
||||||
|
case OperatorNameNode::CommaType:
|
||||||
|
repr = CHILD_TO_BYTEARRAY(1) + ' ' + opNode->toByteArray() + ' ' + CHILD_TO_BYTEARRAY(2);
|
||||||
|
break;
|
||||||
|
case OperatorNameNode::NewType:
|
||||||
|
case OperatorNameNode::DeleteType:
|
||||||
|
case OperatorNameNode::ArrayDeleteType:
|
||||||
|
repr = opNode->toByteArray() + ' ' + CHILD_TO_BYTEARRAY(1);
|
||||||
|
break;
|
||||||
|
default: // Other unary Operators;
|
||||||
|
repr = opNode->toByteArray() + CHILD_TO_BYTEARRAY(1);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case OtherType:
|
||||||
|
repr = pasteAllChildren();
|
||||||
|
}
|
||||||
|
|
||||||
|
return repr;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool OperatorNameNode::mangledRepresentationStartsWith(char c)
|
||||||
|
{
|
||||||
|
return strchr("ndpacmroelgiqsv", c);
|
||||||
|
}
|
||||||
|
|
||||||
|
QByteArray OperatorNameNode::toByteArray() const
|
||||||
|
{
|
||||||
|
switch (m_type) {
|
||||||
|
case NewType: return "new";
|
||||||
|
case ArrayNewType: return "new[]";
|
||||||
|
case DeleteType: return "delete";
|
||||||
|
case ArrayDeleteType: return "delete[]";
|
||||||
|
case UnaryPlusType: case BinaryPlusType: return "+";
|
||||||
|
case UnaryMinusType: case BinaryMinusType: return "-";
|
||||||
|
case UnaryAmpersandType: case BitwiseAndType: return "&";
|
||||||
|
case UnaryStarType: case MultType: return "*";
|
||||||
|
case BitwiseNotType: return "~";
|
||||||
|
case DivType: return "/";
|
||||||
|
case ModuloType: return "%";
|
||||||
|
case BitwiseOrType: return "|";
|
||||||
|
case XorType: return "^";
|
||||||
|
case AssignType: return "=";
|
||||||
|
case IncrementAndAssignType: return "+=";
|
||||||
|
case DecrementAndAssignType: return "-=";
|
||||||
|
case MultAndAssignType: return "*=";
|
||||||
|
case DivAndAssignType: return "/=";
|
||||||
|
case ModuloAndAssignType: return "%=";
|
||||||
|
case BitwiseAndAndAssignType: return "&=";
|
||||||
|
case BitwiseOrAndAssignType: return "|=";
|
||||||
|
case XorAndAssignType: return "^=";
|
||||||
|
case LeftShiftType: return "<<";
|
||||||
|
case RightShiftType: return ">>";
|
||||||
|
case LeftShiftAndAssignType: return "<<=";
|
||||||
|
case RightShiftAndAssignType: return ">>=";
|
||||||
|
case EqualsType: return "==";
|
||||||
|
case NotEqualsType: return "!=";
|
||||||
|
case LessType: return "<";
|
||||||
|
case GreaterType: return ">";
|
||||||
|
case LessEqualType: return "<=";
|
||||||
|
case GreaterEqualType: return ">=";
|
||||||
|
case LogicalNotType: return "!";
|
||||||
|
case LogicalAndType: return "&&";
|
||||||
|
case LogicalOrType: return "||";
|
||||||
|
case IncrementType: return "++";
|
||||||
|
case DecrementType: return "--";
|
||||||
|
case CommaType: return ",";
|
||||||
|
case ArrowStarType: return "->*";
|
||||||
|
case ArrowType: return "->";
|
||||||
|
case CallType: return "()";
|
||||||
|
case IndexType: return "[]";
|
||||||
|
case TernaryType: return "?";
|
||||||
|
case SizeofTypeType: case SizeofExprType: return "sizeof";
|
||||||
|
case AlignofTypeType: case AlignofExprType: return "alignof";
|
||||||
|
case CastType: return ' ' + CHILD_TO_BYTEARRAY(0);
|
||||||
|
case VendorType: return "[vendor extended operator]";
|
||||||
|
}
|
||||||
|
|
||||||
|
DEMANGLER_ASSERT(false);
|
||||||
|
return QByteArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
QByteArray PredefinedBuiltinTypeNode::toByteArray() const
|
||||||
|
{
|
||||||
|
switch (m_type) {
|
||||||
|
case VoidType: return "void";
|
||||||
|
case WCharType: return "wchar_t";
|
||||||
|
case BoolType: return "bool";
|
||||||
|
case PlainCharType: return "char";
|
||||||
|
case SignedCharType: return "signed char";
|
||||||
|
case UnsignedCharType: return "unsigned char";
|
||||||
|
case SignedShortType: return "signed short";
|
||||||
|
case UnsignedShortType: return "unsigned short";
|
||||||
|
case SignedIntType: return "int";
|
||||||
|
case UnsignedIntType: return "unsigned int";
|
||||||
|
case SignedLongType: return "long";
|
||||||
|
case UnsignedLongType: return "unsigned long";
|
||||||
|
case SignedLongLongType: return "long long";
|
||||||
|
case UnsignedLongLongType: return "unsigned long long";
|
||||||
|
case SignedInt128Type: return "__int128";
|
||||||
|
case UnsignedInt128Type: return "unsigned __int128";
|
||||||
|
case FloatType: return "float";
|
||||||
|
case DoubleType: return "double";
|
||||||
|
case LongDoubleType: return "long double";
|
||||||
|
case Float128Type: return "__float128";
|
||||||
|
case EllipsisType: return "...";
|
||||||
|
case DecimalFloatingType16: return "[IEEE 754r half-precision floating point]";
|
||||||
|
case DecimalFloatingType32: return "[IEEE 754r decimal floating point (32 bits)]";
|
||||||
|
case DecimalFloatingType64: return "[IEEE 754r decimal floating point (64 bits)]";
|
||||||
|
case DecimalFloatingType128: return "[IEEE 754r decimal floating point (128 bits)]";
|
||||||
|
case Char32Type: return "char32_t";
|
||||||
|
case Char16Type: return "char16_t";
|
||||||
|
}
|
||||||
|
|
||||||
|
DEMANGLER_ASSERT(false);
|
||||||
|
return QByteArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool ExprPrimaryNode::mangledRepresentationStartsWith(char c)
|
||||||
|
{
|
||||||
|
return c == 'L';
|
||||||
|
}
|
||||||
|
|
||||||
|
QByteArray ExprPrimaryNode::toByteArray() const
|
||||||
|
{
|
||||||
|
return CHILD_TO_BYTEARRAY(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool FunctionTypeNode::mangledRepresentationStartsWith(char c)
|
||||||
|
{
|
||||||
|
return c == 'F';
|
||||||
|
}
|
||||||
|
|
||||||
|
QByteArray FunctionTypeNode::toByteArray() const
|
||||||
|
{
|
||||||
|
return QByteArray(); // Not enough knowledge here to generate a string representation.
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool LocalNameNode::mangledRepresentationStartsWith(char c)
|
||||||
|
{
|
||||||
|
return c == 'Z';
|
||||||
|
}
|
||||||
|
|
||||||
|
QByteArray LocalNameNode::toByteArray() const
|
||||||
|
{
|
||||||
|
QByteArray name;
|
||||||
|
bool hasDiscriminator;
|
||||||
|
if (m_isStringLiteral) {
|
||||||
|
name = CHILD_TO_BYTEARRAY(0) + "::[string literal]";
|
||||||
|
hasDiscriminator = childCount() == 2;
|
||||||
|
} else {
|
||||||
|
name = CHILD_TO_BYTEARRAY(0) + "::" + CHILD_TO_BYTEARRAY(1);
|
||||||
|
hasDiscriminator = childCount() == 3;
|
||||||
|
}
|
||||||
|
if (hasDiscriminator) {
|
||||||
|
const QByteArray discriminator = MY_CHILD_AT(childCount() - 1)->toByteArray();
|
||||||
|
const int rawDiscriminatorValue = discriminator.toInt();
|
||||||
|
name += " (occurrence number " + QByteArray::number(rawDiscriminatorValue - 2) + ')';
|
||||||
|
}
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool MangledNameNode::mangledRepresentationStartsWith(char c)
|
||||||
|
{
|
||||||
|
return c == '_';
|
||||||
|
}
|
||||||
|
|
||||||
|
QByteArray MangledNameNode::toByteArray() const
|
||||||
|
{
|
||||||
|
return pasteAllChildren();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool SourceNameNode::mangledRepresentationStartsWith(char c)
|
||||||
|
{
|
||||||
|
return strchr("123456789", c);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool UnqualifiedNameNode::mangledRepresentationStartsWith(char c)
|
||||||
|
{
|
||||||
|
return OperatorNameNode::mangledRepresentationStartsWith(c)
|
||||||
|
|| CtorDtorNameNode::mangledRepresentationStartsWith(c)
|
||||||
|
|| SourceNameNode::mangledRepresentationStartsWith(c);
|
||||||
|
}
|
||||||
|
|
||||||
|
QByteArray UnqualifiedNameNode::toByteArray() const
|
||||||
|
{
|
||||||
|
QByteArray repr;
|
||||||
|
if (dynamic_cast<OperatorNameNode *>(MY_CHILD_AT(0)))
|
||||||
|
repr = "operator";
|
||||||
|
return repr += CHILD_TO_BYTEARRAY(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool UnqualifiedNameNode::isConstructorOrDestructorOrConversionOperator() const
|
||||||
|
{
|
||||||
|
if (dynamic_cast<CtorDtorNameNode *>(MY_CHILD_AT(0)))
|
||||||
|
return true;
|
||||||
|
const OperatorNameNode * const opNode = dynamic_cast<OperatorNameNode *>(MY_CHILD_AT(0));
|
||||||
|
return opNode && opNode->m_type == OperatorNameNode::CastType;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool UnscopedNameNode::mangledRepresentationStartsWith(char c)
|
||||||
|
{
|
||||||
|
return UnqualifiedNameNode::mangledRepresentationStartsWith(c) || c == 'S';
|
||||||
|
}
|
||||||
|
|
||||||
|
QByteArray UnscopedNameNode::toByteArray() const
|
||||||
|
{
|
||||||
|
QByteArray name = CHILD_TO_BYTEARRAY(0);
|
||||||
|
if (m_inStdNamespace)
|
||||||
|
name.prepend("std::");
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool UnscopedNameNode::isConstructorOrDestructorOrConversionOperator() const
|
||||||
|
{
|
||||||
|
const UnqualifiedNameNode * const childNode
|
||||||
|
= DEMANGLER_CAST(UnqualifiedNameNode, MY_CHILD_AT(0));
|
||||||
|
return childNode->isConstructorOrDestructorOrConversionOperator();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool NestedNameNode::mangledRepresentationStartsWith(char c)
|
||||||
|
{
|
||||||
|
return c == 'N';
|
||||||
|
}
|
||||||
|
|
||||||
|
QByteArray NestedNameNode::toByteArray() const
|
||||||
|
{
|
||||||
|
// This the valid representation only if no cv-qualifiers are present.
|
||||||
|
// In that case (only possible for member functions), a higher-level object must
|
||||||
|
// create the string representation.
|
||||||
|
return CHILD_TO_BYTEARRAY(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool NestedNameNode::isTemplate() const
|
||||||
|
{
|
||||||
|
const PrefixNode * const childNode = DEMANGLER_CAST(PrefixNode, MY_CHILD_AT(childCount() - 1));
|
||||||
|
return childNode->isTemplate();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool NestedNameNode::isConstructorOrDestructorOrConversionOperator() const
|
||||||
|
{
|
||||||
|
const PrefixNode * const childNode = DEMANGLER_CAST(PrefixNode, MY_CHILD_AT(childCount() - 1));
|
||||||
|
return childNode->isConstructorOrDestructorOrConversionOperator();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool SubstitutionNode::mangledRepresentationStartsWith(char c)
|
||||||
|
{
|
||||||
|
return c == 'S';
|
||||||
|
}
|
||||||
|
|
||||||
|
QByteArray SubstitutionNode::toByteArray() const
|
||||||
|
{
|
||||||
|
switch (m_type) {
|
||||||
|
case ActualSubstitutionType: return m_substValue;
|
||||||
|
case StdType: return "std";
|
||||||
|
case StdAllocType: return "std::allocator";
|
||||||
|
case StdBasicStringType: return "std::basic_string";
|
||||||
|
case FullStdBasicStringType: return "std::basic_string<char, std::char_traits<char>, "
|
||||||
|
"std::allocator<char> >";
|
||||||
|
case StdBasicIStreamType: return "std::basic_istream<char, std::char_traits<char> >";
|
||||||
|
case StdBasicOStreamType: return "std::basic_ostream<char, std::char_traits<char> >";
|
||||||
|
case StdBasicIoStreamType: return "std::basic_iostream<char, std::char_traits<char> >";
|
||||||
|
}
|
||||||
|
|
||||||
|
DEMANGLER_ASSERT(false);
|
||||||
|
return QByteArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool PointerToMemberTypeNode::mangledRepresentationStartsWith(char c)
|
||||||
|
{
|
||||||
|
return c == 'M';
|
||||||
|
}
|
||||||
|
|
||||||
|
QByteArray PointerToMemberTypeNode::toByteArray() const
|
||||||
|
{
|
||||||
|
// Gather all qualifiers first, because we have to move them to the end en bloc
|
||||||
|
// .
|
||||||
|
QByteArray qualRepr;
|
||||||
|
const TypeNode *memberTypeNode = DEMANGLER_CAST(TypeNode, MY_CHILD_AT(1));
|
||||||
|
while (memberTypeNode->m_type == TypeNode::QualifiedType) {
|
||||||
|
const CvQualifiersNode * const cvNode
|
||||||
|
= DEMANGLER_CAST(CvQualifiersNode, CHILD_AT(memberTypeNode, 0));
|
||||||
|
if (cvNode->m_hasConst || cvNode->m_hasVolatile) {
|
||||||
|
if (!qualRepr.isEmpty())
|
||||||
|
qualRepr += ' ';
|
||||||
|
qualRepr += cvNode->toByteArray();
|
||||||
|
}
|
||||||
|
memberTypeNode = DEMANGLER_CAST(TypeNode, CHILD_AT(memberTypeNode, 1));
|
||||||
|
}
|
||||||
|
|
||||||
|
QByteArray repr;
|
||||||
|
const QByteArray classTypeRepr = CHILD_TO_BYTEARRAY(0);
|
||||||
|
const FunctionTypeNode * const functionNode
|
||||||
|
= dynamic_cast<const FunctionTypeNode *>(CHILD_AT(memberTypeNode, 0));
|
||||||
|
if (functionNode) {
|
||||||
|
const BareFunctionTypeNode * const bareFunctionNode
|
||||||
|
= DEMANGLER_CAST(BareFunctionTypeNode, CHILD_AT(functionNode, 0));
|
||||||
|
if (functionNode->m_isExternC)
|
||||||
|
repr += "extern \"C\" ";
|
||||||
|
if (bareFunctionNode->m_hasReturnType)
|
||||||
|
repr += CHILD_AT(bareFunctionNode, 0)->toByteArray() + ' ';
|
||||||
|
repr += '(' + classTypeRepr + "::*)" + bareFunctionNode->toByteArray();
|
||||||
|
if (!qualRepr.isEmpty())
|
||||||
|
repr += ' ' + qualRepr;
|
||||||
|
} else {
|
||||||
|
repr = memberTypeNode->toByteArray() + ' ' + classTypeRepr + "::";
|
||||||
|
if (!qualRepr.isEmpty())
|
||||||
|
repr += qualRepr + ' ';
|
||||||
|
repr += '*';
|
||||||
|
}
|
||||||
|
return repr;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
TemplateParamNode::~TemplateParamNode()
|
||||||
|
{
|
||||||
|
clearChildList(); // Child node is deleted elsewhere.
|
||||||
|
}
|
||||||
|
|
||||||
|
bool TemplateParamNode::mangledRepresentationStartsWith(char c)
|
||||||
|
{
|
||||||
|
return c == 'T';
|
||||||
|
}
|
||||||
|
|
||||||
|
QByteArray TemplateParamNode::toByteArray() const
|
||||||
|
{
|
||||||
|
return CHILD_TO_BYTEARRAY(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool TemplateArgsNode::mangledRepresentationStartsWith(char c)
|
||||||
|
{
|
||||||
|
return c == 'I';
|
||||||
|
}
|
||||||
|
|
||||||
|
QByteArray TemplateArgsNode::toByteArray() const
|
||||||
|
{
|
||||||
|
QByteArray repr = "<";
|
||||||
|
for (int i = 0; i < childCount(); ++i) {
|
||||||
|
repr += CHILD_TO_BYTEARRAY(i);
|
||||||
|
if (i < childCount() - 1)
|
||||||
|
repr += ", ";
|
||||||
|
}
|
||||||
|
return repr += '>';
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool SpecialNameNode::mangledRepresentationStartsWith(char c)
|
||||||
|
{
|
||||||
|
return c == 'T' || c == 'G';
|
||||||
|
}
|
||||||
|
|
||||||
|
QByteArray SpecialNameNode::toByteArray() const
|
||||||
|
{
|
||||||
|
switch (m_type) {
|
||||||
|
case VirtualTableType:
|
||||||
|
return "[virtual table of " + CHILD_TO_BYTEARRAY(0) + ']';
|
||||||
|
case VttStructType:
|
||||||
|
return "[VTT struct of " + CHILD_TO_BYTEARRAY(0) + ']';
|
||||||
|
case TypeInfoType:
|
||||||
|
return "typeid(" + CHILD_TO_BYTEARRAY(0) + ')';
|
||||||
|
case TypeInfoNameType:
|
||||||
|
return "typeid(" + CHILD_TO_BYTEARRAY(0) + ").name()";
|
||||||
|
case GuardVarType:
|
||||||
|
return "[guard variable of " + CHILD_TO_BYTEARRAY(0) + ']';
|
||||||
|
case SingleCallOffsetType:
|
||||||
|
return "[offset:" + CHILD_TO_BYTEARRAY(0) + ']' + CHILD_TO_BYTEARRAY(1);
|
||||||
|
case DoubleCallOffsetType:
|
||||||
|
return "[this-adjustment:" + CHILD_TO_BYTEARRAY(0) + "][result-adjustment:"
|
||||||
|
+ CHILD_TO_BYTEARRAY(1) + ']' + CHILD_TO_BYTEARRAY(2);
|
||||||
|
}
|
||||||
|
|
||||||
|
DEMANGLER_ASSERT(false);
|
||||||
|
return QByteArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool NumberNode::mangledRepresentationStartsWith(char c, int base)
|
||||||
|
{
|
||||||
|
return NonNegativeNumberNode::mangledRepresentationStartsWith(c, base) || c == 'n';
|
||||||
|
}
|
||||||
|
|
||||||
|
QByteArray NumberNode::toByteArray() const
|
||||||
|
{
|
||||||
|
QByteArray repr = CHILD_TO_BYTEARRAY(0);
|
||||||
|
if (m_isNegative)
|
||||||
|
repr.prepend('-');
|
||||||
|
return repr;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool NonNegativeNumberNode::mangledRepresentationStartsWith(char c, int base)
|
||||||
|
{
|
||||||
|
// Base can only be 10 or 36.
|
||||||
|
if (base == 10)
|
||||||
|
return strchr("0123456789", c);
|
||||||
|
else
|
||||||
|
return strchr("0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ", c);
|
||||||
|
}
|
||||||
|
|
||||||
|
QByteArray NonNegativeNumberNode::toByteArray() const
|
||||||
|
{
|
||||||
|
return QByteArray::number(m_number);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool NameNode::mangledRepresentationStartsWith(char c)
|
||||||
|
{
|
||||||
|
return NestedNameNode::mangledRepresentationStartsWith(c)
|
||||||
|
|| UnscopedNameNode::mangledRepresentationStartsWith(c)
|
||||||
|
|| SubstitutionNode::mangledRepresentationStartsWith(c)
|
||||||
|
|| LocalNameNode::mangledRepresentationStartsWith(c);
|
||||||
|
}
|
||||||
|
|
||||||
|
QByteArray NameNode::toByteArray() const
|
||||||
|
{
|
||||||
|
return pasteAllChildren();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool NameNode::isTemplate() const
|
||||||
|
{
|
||||||
|
if (childCount() > 1 && dynamic_cast<TemplateArgsNode *>(MY_CHILD_AT(1)))
|
||||||
|
return true;
|
||||||
|
const NestedNameNode * const nestedNameNode = dynamic_cast<NestedNameNode *>(MY_CHILD_AT(0));
|
||||||
|
if (nestedNameNode)
|
||||||
|
return nestedNameNode->isTemplate();
|
||||||
|
|
||||||
|
// TODO: Is <local-name> relevant?
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool NameNode::isConstructorOrDestructorOrConversionOperator() const
|
||||||
|
{
|
||||||
|
const NestedNameNode * const nestedNameNode = dynamic_cast<NestedNameNode *>(MY_CHILD_AT(0));
|
||||||
|
if (nestedNameNode)
|
||||||
|
return nestedNameNode->isConstructorOrDestructorOrConversionOperator();
|
||||||
|
|
||||||
|
// TODO: Is <local-name> relevant?
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool TemplateArgNode::mangledRepresentationStartsWith(char c)
|
||||||
|
{
|
||||||
|
return TypeNode::mangledRepresentationStartsWith(c)
|
||||||
|
|| ExprPrimaryNode::mangledRepresentationStartsWith(c)
|
||||||
|
|| c == 'X' || c == 'I' || c == 's';
|
||||||
|
}
|
||||||
|
|
||||||
|
QByteArray TemplateArgNode::toByteArray() const
|
||||||
|
{
|
||||||
|
if (m_isTemplateArgumentPack) {
|
||||||
|
QByteArray repr;
|
||||||
|
for (int i = 0; i < childCount(); ++i) {
|
||||||
|
if (i > 0 && i < childCount() - 1)
|
||||||
|
repr += ", "; // TODO: Probably not the right syntax
|
||||||
|
repr += CHILD_TO_BYTEARRAY(i);
|
||||||
|
}
|
||||||
|
return repr;
|
||||||
|
}
|
||||||
|
return CHILD_TO_BYTEARRAY(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Prefix2Node::mangledRepresentationStartsWith(char c)
|
||||||
|
{
|
||||||
|
return UnqualifiedNameNode::mangledRepresentationStartsWith(c);
|
||||||
|
}
|
||||||
|
|
||||||
|
QByteArray Prefix2Node::toByteArray() const
|
||||||
|
{
|
||||||
|
if (childCount() == 0)
|
||||||
|
return QByteArray();
|
||||||
|
QByteArray repr = CHILD_TO_BYTEARRAY(0);
|
||||||
|
for (int i = 1; i < childCount(); ++i) {
|
||||||
|
if (dynamic_cast<UnqualifiedNameNode *>(MY_CHILD_AT(i)))
|
||||||
|
repr += "::"; // Don't show the "global namespace" indicator.
|
||||||
|
repr += CHILD_TO_BYTEARRAY(i);
|
||||||
|
}
|
||||||
|
return repr;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Prefix2Node::isTemplate() const
|
||||||
|
{
|
||||||
|
return dynamic_cast<TemplateArgsNode *>(MY_CHILD_AT(childCount() - 1));
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Prefix2Node::isConstructorOrDestructorOrConversionOperator() const
|
||||||
|
{
|
||||||
|
for (int i = childCount() - 1; i >= 0; --i) {
|
||||||
|
const UnqualifiedNameNode * const n = dynamic_cast<UnqualifiedNameNode *>(MY_CHILD_AT(i));
|
||||||
|
if (n)
|
||||||
|
return n->isConstructorOrDestructorOrConversionOperator();
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool PrefixNode::mangledRepresentationStartsWith(char c)
|
||||||
|
{
|
||||||
|
return TemplateParamNode::mangledRepresentationStartsWith(c)
|
||||||
|
|| SubstitutionNode::mangledRepresentationStartsWith(c)
|
||||||
|
|| Prefix2Node::mangledRepresentationStartsWith(c);
|
||||||
|
}
|
||||||
|
|
||||||
|
QByteArray PrefixNode::toByteArray() const
|
||||||
|
{
|
||||||
|
if (childCount() == 1)
|
||||||
|
return CHILD_TO_BYTEARRAY(0);
|
||||||
|
if (MY_CHILD_AT(childCount() - 1)->childCount() == 0) // Empty prefix2, i.e. no symbol follows.
|
||||||
|
return pasteAllChildren();
|
||||||
|
if (childCount() == 2)
|
||||||
|
return CHILD_TO_BYTEARRAY(0) + "::" + CHILD_TO_BYTEARRAY(1);
|
||||||
|
return CHILD_TO_BYTEARRAY(0) + CHILD_TO_BYTEARRAY(1) + "::" + CHILD_TO_BYTEARRAY(2);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool PrefixNode::isTemplate() const
|
||||||
|
{
|
||||||
|
if (childCount() > 1 && dynamic_cast<TemplateArgsNode *>(CHILD_AT(this, 1)))
|
||||||
|
return true;
|
||||||
|
const Prefix2Node * const childNode
|
||||||
|
= DEMANGLER_CAST(Prefix2Node, MY_CHILD_AT(childCount() - 1));
|
||||||
|
return childNode->isTemplate();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool PrefixNode::isConstructorOrDestructorOrConversionOperator() const
|
||||||
|
{
|
||||||
|
const Prefix2Node * const childNode
|
||||||
|
= DEMANGLER_CAST(Prefix2Node, MY_CHILD_AT(childCount() - 1));
|
||||||
|
return childNode->isConstructorOrDestructorOrConversionOperator();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool TypeNode::mangledRepresentationStartsWith(char c)
|
||||||
|
{
|
||||||
|
return BuiltinTypeNode::mangledRepresentationStartsWith(c)
|
||||||
|
|| FunctionTypeNode::mangledRepresentationStartsWith(c)
|
||||||
|
|| ClassEnumTypeNode::mangledRepresentationStartsWith(c)
|
||||||
|
|| ArrayTypeNode::mangledRepresentationStartsWith(c)
|
||||||
|
|| PointerToMemberTypeNode::mangledRepresentationStartsWith(c)
|
||||||
|
|| TemplateParamNode::mangledRepresentationStartsWith(c)
|
||||||
|
|| SubstitutionNode::mangledRepresentationStartsWith(c)
|
||||||
|
|| CvQualifiersNode::mangledRepresentationStartsWith(c)
|
||||||
|
|| strchr("PROCGUD", c);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
QByteArray TypeNode::toByteArray() const
|
||||||
|
{
|
||||||
|
// A pure top-down approach is not possible to due to the weird function pointer syntax,
|
||||||
|
// e.g. things like (* const &)(int) etc.
|
||||||
|
// Instead, we have to gather all successive qualifiers, pointers and references first
|
||||||
|
// and then apply them as a whole to whatever follows.
|
||||||
|
// Note that "qualifier to function" is not possible here, since that is handled by
|
||||||
|
// PointerToMemberType.
|
||||||
|
QList<const ParseTreeNode *> qualPtrRefList;
|
||||||
|
const TypeNode *currentNode = this;
|
||||||
|
bool leafType = false;
|
||||||
|
while (!leafType) {
|
||||||
|
switch (currentNode->m_type) {
|
||||||
|
case QualifiedType: {
|
||||||
|
const CvQualifiersNode * const cvNode
|
||||||
|
= DEMANGLER_CAST(CvQualifiersNode, CHILD_AT(currentNode, 0));
|
||||||
|
if (cvNode->m_hasConst || cvNode->m_hasVolatile)
|
||||||
|
qualPtrRefList << cvNode;
|
||||||
|
currentNode = DEMANGLER_CAST(TypeNode, CHILD_AT(currentNode, 1));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case PointerType: case ReferenceType: case RValueType:
|
||||||
|
qualPtrRefList << currentNode;
|
||||||
|
currentNode = DEMANGLER_CAST(TypeNode, CHILD_AT(currentNode, 0));
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
leafType = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (qualPtrRefList.isEmpty()) {
|
||||||
|
switch (currentNode->m_type) {
|
||||||
|
case PackExpansionType: return CHILD_TO_BYTEARRAY(0); // TODO: What's the syntax?
|
||||||
|
case DeclType: return "decltype(" + CHILD_TO_BYTEARRAY(0) + ')';
|
||||||
|
case VendorType: return pasteAllChildren();
|
||||||
|
case OtherType: return pasteAllChildren();
|
||||||
|
default: DEMANGLER_ASSERT(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return toByteArrayQualPointerRef(currentNode, qualPtrRefListToByteArray(qualPtrRefList));
|
||||||
|
}
|
||||||
|
|
||||||
|
QByteArray TypeNode::toByteArrayQualPointerRef(const TypeNode *typeNode,
|
||||||
|
const QByteArray &qualPtrRef) const
|
||||||
|
{
|
||||||
|
const FunctionTypeNode * const functionNode
|
||||||
|
= dynamic_cast<FunctionTypeNode *>(CHILD_AT(typeNode, 0));
|
||||||
|
if (functionNode) {
|
||||||
|
const BareFunctionTypeNode * const bareFunctionNode
|
||||||
|
= DEMANGLER_CAST(BareFunctionTypeNode, CHILD_AT(functionNode, 0));
|
||||||
|
QByteArray repr;
|
||||||
|
if (functionNode->m_isExternC)
|
||||||
|
repr += "extern \"C\" ";
|
||||||
|
if (bareFunctionNode->m_hasReturnType)
|
||||||
|
repr += CHILD_AT(bareFunctionNode, 0)->toByteArray() + ' ';
|
||||||
|
return repr += '(' + qualPtrRef + ')' + bareFunctionNode->toByteArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dynamic_cast<PointerToMemberTypeNode *>(CHILD_AT(typeNode, 0)))
|
||||||
|
return typeNode->toByteArray() + qualPtrRef;
|
||||||
|
|
||||||
|
return typeNode->toByteArray() + ' ' + qualPtrRef;
|
||||||
|
}
|
||||||
|
|
||||||
|
QByteArray TypeNode::qualPtrRefListToByteArray(const QList<const ParseTreeNode *> &nodeList) const
|
||||||
|
{
|
||||||
|
QByteArray repr;
|
||||||
|
foreach (const ParseTreeNode * const n, nodeList) {
|
||||||
|
const TypeNode * const typeNode = dynamic_cast<const TypeNode *>(n);
|
||||||
|
if (typeNode) {
|
||||||
|
switch (typeNode->m_type) {
|
||||||
|
case PointerType:
|
||||||
|
if (!repr.isEmpty() && !repr.startsWith('*'))
|
||||||
|
repr.prepend(' ');
|
||||||
|
repr.prepend('*');
|
||||||
|
break;
|
||||||
|
case ReferenceType:
|
||||||
|
if (!repr.isEmpty())
|
||||||
|
repr.prepend(' ');
|
||||||
|
repr.prepend('&');
|
||||||
|
break;
|
||||||
|
case RValueType:
|
||||||
|
if (!repr.isEmpty())
|
||||||
|
repr.prepend(' ');
|
||||||
|
repr.prepend("&&");
|
||||||
|
default:
|
||||||
|
DEMANGLER_ASSERT(false);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (!repr.isEmpty())
|
||||||
|
repr.prepend(' ');
|
||||||
|
repr.prepend(n->toByteArray());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return repr;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool FloatValueNode::mangledRepresentationStartsWith(char c)
|
||||||
|
{
|
||||||
|
return strchr("0123456789abcdef", c);
|
||||||
|
}
|
||||||
|
|
||||||
|
QByteArray FloatValueNode::toByteArray() const
|
||||||
|
{
|
||||||
|
return QByteArray::number(m_value);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace Internal
|
||||||
|
} // namespace Debugger
|
||||||
429
src/plugins/debugger/namedemangler/parsetreenodes.h
Normal file
429
src/plugins/debugger/namedemangler/parsetreenodes.h
Normal file
@@ -0,0 +1,429 @@
|
|||||||
|
/**************************************************************************
|
||||||
|
**
|
||||||
|
** This file is part of Qt Creator
|
||||||
|
**
|
||||||
|
** Copyright (c) 2012 Nokia Corporation and/or its subsidiary(-ies).
|
||||||
|
**
|
||||||
|
** Contact: Nokia Corporation (qt-info@nokia.com)
|
||||||
|
**
|
||||||
|
**
|
||||||
|
** GNU Lesser General Public License Usage
|
||||||
|
**
|
||||||
|
** This file may be used under the terms of the GNU Lesser General Public
|
||||||
|
** License version 2.1 as published by the Free Software Foundation and
|
||||||
|
** appearing in the file LICENSE.LGPL included in the packaging of this file.
|
||||||
|
** Please review the following information to ensure the GNU Lesser General
|
||||||
|
** Public License version 2.1 requirements will be met:
|
||||||
|
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||||
|
**
|
||||||
|
** In addition, as a special exception, Nokia gives you certain additional
|
||||||
|
** rights. These rights are described in the Nokia Qt LGPL Exception
|
||||||
|
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||||
|
**
|
||||||
|
** Other Usage
|
||||||
|
**
|
||||||
|
** Alternatively, this file may be used in accordance with the terms and
|
||||||
|
** conditions contained in a signed written agreement between you and Nokia.
|
||||||
|
**
|
||||||
|
** If you have questions regarding the use of this file, please contact
|
||||||
|
** Nokia at qt-info@nokia.com.
|
||||||
|
**
|
||||||
|
**************************************************************************/
|
||||||
|
#ifndef PARSETREENODES_H
|
||||||
|
#define PARSETREENODES_H
|
||||||
|
|
||||||
|
#include <QByteArray>
|
||||||
|
#include <QList>
|
||||||
|
#include <QSet>
|
||||||
|
|
||||||
|
#define CHILD_AT(obj, index) obj->childAt(index, Q_FUNC_INFO, __FILE__, __LINE__)
|
||||||
|
|
||||||
|
namespace Debugger {
|
||||||
|
namespace Internal {
|
||||||
|
|
||||||
|
class ParseTreeNode
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual ~ParseTreeNode();
|
||||||
|
virtual QByteArray toByteArray() const = 0;
|
||||||
|
|
||||||
|
int childCount() const { return m_children.count(); }
|
||||||
|
void addChild(ParseTreeNode *childNode) { m_children << childNode; }
|
||||||
|
ParseTreeNode *childAt(int i, const QString &func, const QString &file, int line) const;
|
||||||
|
QByteArray pasteAllChildren() const;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void clearChildList() { m_children.clear(); }
|
||||||
|
|
||||||
|
private:
|
||||||
|
QList<ParseTreeNode *> m_children; // Convention: Children are inserted in parse order.
|
||||||
|
};
|
||||||
|
|
||||||
|
class ArrayTypeNode : public ParseTreeNode
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static bool mangledRepresentationStartsWith(char c);
|
||||||
|
|
||||||
|
QByteArray toByteArray() const;
|
||||||
|
};
|
||||||
|
|
||||||
|
class BareFunctionTypeNode : public ParseTreeNode
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static bool mangledRepresentationStartsWith(char c);
|
||||||
|
|
||||||
|
QByteArray toByteArray() const;
|
||||||
|
|
||||||
|
bool m_hasReturnType;
|
||||||
|
};
|
||||||
|
|
||||||
|
class BuiltinTypeNode : public ParseTreeNode
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static bool mangledRepresentationStartsWith(char c);
|
||||||
|
|
||||||
|
QByteArray toByteArray() const;
|
||||||
|
};
|
||||||
|
|
||||||
|
class PredefinedBuiltinTypeNode : public ParseTreeNode
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
QByteArray toByteArray() const;
|
||||||
|
|
||||||
|
enum Type {
|
||||||
|
VoidType, WCharType, BoolType,
|
||||||
|
PlainCharType, SignedCharType, UnsignedCharType, SignedShortType, UnsignedShortType,
|
||||||
|
SignedIntType, UnsignedIntType, SignedLongType, UnsignedLongType,
|
||||||
|
SignedLongLongType, UnsignedLongLongType, SignedInt128Type, UnsignedInt128Type,
|
||||||
|
FloatType, DoubleType, LongDoubleType, Float128Type, EllipsisType,
|
||||||
|
DecimalFloatingType64, DecimalFloatingType128, DecimalFloatingType32,
|
||||||
|
DecimalFloatingType16, Char32Type, Char16Type
|
||||||
|
} m_type;
|
||||||
|
};
|
||||||
|
|
||||||
|
class CallOffsetNode : public ParseTreeNode
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static bool mangledRepresentationStartsWith(char c);
|
||||||
|
|
||||||
|
QByteArray toByteArray() const;
|
||||||
|
};
|
||||||
|
|
||||||
|
class NvOffsetNode : public ParseTreeNode
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
QByteArray toByteArray() const { return QByteArray(); } // TODO: How to encode this?
|
||||||
|
};
|
||||||
|
|
||||||
|
class VOffsetNode : public ParseTreeNode
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
QByteArray toByteArray() const { return QByteArray(); } // TODO: How to encode this?
|
||||||
|
};
|
||||||
|
|
||||||
|
class ClassEnumTypeNode : public ParseTreeNode
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static bool mangledRepresentationStartsWith(char c);
|
||||||
|
|
||||||
|
QByteArray toByteArray() const;
|
||||||
|
};
|
||||||
|
|
||||||
|
class DiscriminatorNode : public ParseTreeNode
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static bool mangledRepresentationStartsWith(char c);
|
||||||
|
|
||||||
|
QByteArray toByteArray() const;
|
||||||
|
};
|
||||||
|
|
||||||
|
class CtorDtorNameNode : public ParseTreeNode
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static bool mangledRepresentationStartsWith(char c);
|
||||||
|
|
||||||
|
QByteArray toByteArray() const;
|
||||||
|
|
||||||
|
bool m_isDestructor;
|
||||||
|
QByteArray m_representation;
|
||||||
|
};
|
||||||
|
|
||||||
|
class CvQualifiersNode : public ParseTreeNode
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static bool mangledRepresentationStartsWith(char c);
|
||||||
|
|
||||||
|
QByteArray toByteArray() const;
|
||||||
|
|
||||||
|
bool m_hasVolatile;
|
||||||
|
bool m_hasConst;
|
||||||
|
};
|
||||||
|
|
||||||
|
class EncodingNode : public ParseTreeNode
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static bool mangledRepresentationStartsWith(char c);
|
||||||
|
|
||||||
|
QByteArray toByteArray() const;
|
||||||
|
};
|
||||||
|
|
||||||
|
class ExpressionNode : public ParseTreeNode
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static bool mangledRepresentationStartsWith(char c);
|
||||||
|
|
||||||
|
QByteArray toByteArray() const;
|
||||||
|
|
||||||
|
enum Type {
|
||||||
|
ConversionType, SizeofType, AlignofType, OperatorType, OtherType, ParameterPackSizeType
|
||||||
|
} m_type;
|
||||||
|
};
|
||||||
|
|
||||||
|
class OperatorNameNode : public ParseTreeNode
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static bool mangledRepresentationStartsWith(char c);
|
||||||
|
|
||||||
|
QByteArray toByteArray() const;
|
||||||
|
|
||||||
|
enum Type {
|
||||||
|
NewType, ArrayNewType, DeleteType, ArrayDeleteType, UnaryPlusType, UnaryMinusType,
|
||||||
|
UnaryAmpersandType, UnaryStarType, BitwiseNotType, BinaryPlusType, BinaryMinusType,
|
||||||
|
MultType, DivType, ModuloType, BitwiseAndType, BitwiseOrType, XorType, AssignType,
|
||||||
|
IncrementAndAssignType, DecrementAndAssignType, MultAndAssignType, DivAndAssignType,
|
||||||
|
ModuloAndAssignType, BitwiseAndAndAssignType, BitwiseOrAndAssignType, XorAndAssignType,
|
||||||
|
LeftShiftType, RightShiftType, LeftShiftAndAssignType, RightShiftAndAssignType, EqualsType,
|
||||||
|
NotEqualsType, LessType, GreaterType, LessEqualType, GreaterEqualType, LogicalNotType,
|
||||||
|
LogicalAndType, LogicalOrType, IncrementType, DecrementType, CommaType, ArrowStarType,
|
||||||
|
ArrowType, CallType, IndexType, TernaryType, SizeofTypeType, SizeofExprType,
|
||||||
|
AlignofTypeType, AlignofExprType, CastType, VendorType
|
||||||
|
} m_type;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
class ExprPrimaryNode : public ParseTreeNode
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static bool mangledRepresentationStartsWith(char c);
|
||||||
|
|
||||||
|
QByteArray toByteArray() const;
|
||||||
|
};
|
||||||
|
|
||||||
|
class FunctionTypeNode : public ParseTreeNode
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static bool mangledRepresentationStartsWith(char c);
|
||||||
|
|
||||||
|
QByteArray toByteArray() const;
|
||||||
|
|
||||||
|
bool m_isExternC;
|
||||||
|
};
|
||||||
|
|
||||||
|
class LocalNameNode : public ParseTreeNode
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static bool mangledRepresentationStartsWith(char c);
|
||||||
|
|
||||||
|
QByteArray toByteArray() const;
|
||||||
|
|
||||||
|
bool m_isStringLiteral;
|
||||||
|
};
|
||||||
|
|
||||||
|
class MangledNameNode : public ParseTreeNode
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static bool mangledRepresentationStartsWith(char c);
|
||||||
|
|
||||||
|
QByteArray toByteArray() const;
|
||||||
|
};
|
||||||
|
|
||||||
|
class NumberNode : public ParseTreeNode
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static bool mangledRepresentationStartsWith(char c, int base = 10);
|
||||||
|
|
||||||
|
QByteArray toByteArray() const;
|
||||||
|
|
||||||
|
bool m_isNegative;
|
||||||
|
};
|
||||||
|
|
||||||
|
class SourceNameNode : public ParseTreeNode
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static bool mangledRepresentationStartsWith(char c);
|
||||||
|
|
||||||
|
QByteArray toByteArray() const { return m_name; }
|
||||||
|
|
||||||
|
QByteArray m_name;
|
||||||
|
};
|
||||||
|
|
||||||
|
class UnqualifiedNameNode : public ParseTreeNode
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static bool mangledRepresentationStartsWith(char c);
|
||||||
|
|
||||||
|
QByteArray toByteArray() const;
|
||||||
|
|
||||||
|
bool isConstructorOrDestructorOrConversionOperator() const;
|
||||||
|
};
|
||||||
|
|
||||||
|
class UnscopedNameNode : public ParseTreeNode
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static bool mangledRepresentationStartsWith(char c);
|
||||||
|
|
||||||
|
QByteArray toByteArray() const;
|
||||||
|
|
||||||
|
bool isConstructorOrDestructorOrConversionOperator() const;
|
||||||
|
|
||||||
|
bool m_inStdNamespace;
|
||||||
|
};
|
||||||
|
|
||||||
|
class NestedNameNode : public ParseTreeNode
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static bool mangledRepresentationStartsWith(char c);
|
||||||
|
|
||||||
|
QByteArray toByteArray() const;
|
||||||
|
|
||||||
|
bool isTemplate() const;
|
||||||
|
bool isConstructorOrDestructorOrConversionOperator() const;
|
||||||
|
};
|
||||||
|
|
||||||
|
class SubstitutionNode : public ParseTreeNode
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static bool mangledRepresentationStartsWith(char c);
|
||||||
|
|
||||||
|
QByteArray toByteArray() const;
|
||||||
|
|
||||||
|
enum Type {
|
||||||
|
ActualSubstitutionType, StdType, StdAllocType, StdBasicStringType, FullStdBasicStringType,
|
||||||
|
StdBasicIStreamType, StdBasicOStreamType, StdBasicIoStreamType
|
||||||
|
} m_type;
|
||||||
|
QByteArray m_substValue;
|
||||||
|
};
|
||||||
|
|
||||||
|
class PointerToMemberTypeNode : public ParseTreeNode
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static bool mangledRepresentationStartsWith(char c);
|
||||||
|
|
||||||
|
QByteArray toByteArray() const;
|
||||||
|
};
|
||||||
|
|
||||||
|
class TemplateParamNode : public ParseTreeNode
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
~TemplateParamNode();
|
||||||
|
|
||||||
|
static bool mangledRepresentationStartsWith(char c);
|
||||||
|
|
||||||
|
QByteArray toByteArray() const;
|
||||||
|
};
|
||||||
|
|
||||||
|
class TemplateArgsNode : public ParseTreeNode
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static bool mangledRepresentationStartsWith(char c);
|
||||||
|
|
||||||
|
QByteArray toByteArray() const;
|
||||||
|
};
|
||||||
|
|
||||||
|
class SpecialNameNode : public ParseTreeNode
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static bool mangledRepresentationStartsWith(char c);
|
||||||
|
|
||||||
|
QByteArray toByteArray() const;
|
||||||
|
|
||||||
|
enum Type {
|
||||||
|
VirtualTableType, VttStructType, TypeInfoType, TypeInfoNameType, GuardVarType,
|
||||||
|
SingleCallOffsetType, DoubleCallOffsetType
|
||||||
|
} m_type;
|
||||||
|
};
|
||||||
|
|
||||||
|
class NonNegativeNumberNode : public ParseTreeNode
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static bool mangledRepresentationStartsWith(char c, int base = 10);
|
||||||
|
|
||||||
|
QByteArray toByteArray() const;
|
||||||
|
|
||||||
|
quint64 m_number;
|
||||||
|
};
|
||||||
|
|
||||||
|
class NameNode : public ParseTreeNode
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static bool mangledRepresentationStartsWith(char c);
|
||||||
|
|
||||||
|
QByteArray toByteArray() const;
|
||||||
|
|
||||||
|
bool isTemplate() const;
|
||||||
|
bool isConstructorOrDestructorOrConversionOperator() const;
|
||||||
|
};
|
||||||
|
|
||||||
|
class TemplateArgNode : public ParseTreeNode
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static bool mangledRepresentationStartsWith(char c);
|
||||||
|
|
||||||
|
QByteArray toByteArray() const;
|
||||||
|
|
||||||
|
bool m_isTemplateArgumentPack;
|
||||||
|
};
|
||||||
|
|
||||||
|
class Prefix2Node : public ParseTreeNode
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static bool mangledRepresentationStartsWith(char c);
|
||||||
|
|
||||||
|
QByteArray toByteArray() const;
|
||||||
|
|
||||||
|
bool isTemplate() const;
|
||||||
|
bool isConstructorOrDestructorOrConversionOperator() const;
|
||||||
|
};
|
||||||
|
|
||||||
|
class PrefixNode : public ParseTreeNode
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static bool mangledRepresentationStartsWith(char c);
|
||||||
|
|
||||||
|
QByteArray toByteArray() const;
|
||||||
|
|
||||||
|
bool isTemplate() const;
|
||||||
|
bool isConstructorOrDestructorOrConversionOperator() const;
|
||||||
|
};
|
||||||
|
|
||||||
|
class TypeNode : public ParseTreeNode
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static bool mangledRepresentationStartsWith(char c);
|
||||||
|
|
||||||
|
QByteArray toByteArray() const;
|
||||||
|
|
||||||
|
QByteArray toByteArrayQualPointerRef(const TypeNode *typeNode,
|
||||||
|
const QByteArray &qualPtrRef) const;
|
||||||
|
QByteArray qualPtrRefListToByteArray(const QList<const ParseTreeNode *> &nodeList) const;
|
||||||
|
|
||||||
|
enum Type {
|
||||||
|
QualifiedType, PointerType, ReferenceType, RValueType, VendorType, PackExpansionType,
|
||||||
|
DeclType, OtherType
|
||||||
|
} m_type;
|
||||||
|
};
|
||||||
|
|
||||||
|
class FloatValueNode : public ParseTreeNode
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static bool mangledRepresentationStartsWith(char c);
|
||||||
|
|
||||||
|
QByteArray toByteArray() const;
|
||||||
|
|
||||||
|
double m_value;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace Internal
|
||||||
|
} // namespace Debugger
|
||||||
|
|
||||||
|
#endif // PARSETREENODES_H
|
||||||
@@ -1,7 +1,15 @@
|
|||||||
include(../qttest.pri)
|
include(../qttest.pri)
|
||||||
|
|
||||||
|
APPSOURCEDIR = $$CREATORSOURCEDIR/src/plugins/qt4projectmanager/wizards
|
||||||
|
LIBS *= -L$$IDE_LIBRARY_PATH -lUtils
|
||||||
|
|
||||||
DEBUGGERDIR = $$IDE_SOURCE_TREE/src/plugins/debugger
|
DEBUGGERDIR = $$IDE_SOURCE_TREE/src/plugins/debugger
|
||||||
INCLUDEPATH += $$DEBUGGERDIR
|
INCLUDEPATH += $$DEBUGGERDIR
|
||||||
|
|
||||||
HEADERS += $$DEBUGGERDIR/name_demangler.h
|
HEADERS += \
|
||||||
SOURCES += tst_namedemangler.cpp $$DEBUGGERDIR/name_demangler.cpp
|
$$DEBUGGERDIR/namedemangler/namedemangler.h \
|
||||||
|
$$DEBUGGERDIR/namedemangler/parsetreenodes.h
|
||||||
|
SOURCES += \
|
||||||
|
tst_namedemangler.cpp \
|
||||||
|
$$DEBUGGERDIR/namedemangler/namedemangler.cpp \
|
||||||
|
$$DEBUGGERDIR/namedemangler/parsetreenodes.cpp
|
||||||
|
|||||||
@@ -29,11 +29,18 @@
|
|||||||
** Nokia at qt-info@nokia.com.
|
** Nokia at qt-info@nokia.com.
|
||||||
**
|
**
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
#include <name_demangler.h>
|
#include <namedemangler/namedemangler.h>
|
||||||
|
#include <namedemangler/parsetreenodes.h>
|
||||||
|
|
||||||
#include <QObject>
|
#include <QObject>
|
||||||
#include <QTest>
|
#include <QTest>
|
||||||
|
|
||||||
|
#define TEST_CORRECTLY_MANGLED_NAME(mangled, expectedDemangled) \
|
||||||
|
do { \
|
||||||
|
QVERIFY2(demangler.demangle(mangled), qPrintable(demangler.errorString())); \
|
||||||
|
QCOMPARE(demangler.demangledName(), QLatin1String(expectedDemangled)); \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
using namespace Debugger::Internal;
|
using namespace Debugger::Internal;
|
||||||
|
|
||||||
class NameDemanglerAutoTest : public QObject
|
class NameDemanglerAutoTest : public QObject
|
||||||
@@ -41,12 +48,11 @@ class NameDemanglerAutoTest : public QObject
|
|||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
private slots:
|
private slots:
|
||||||
void testUnmangledName();
|
void testUnmangledName();
|
||||||
void testCorrectlyMangledNames();
|
void testDisjunctFirstSets();
|
||||||
|
void TEST_CORRECTLY_MANGLED_NAMEs();
|
||||||
void testIncorrectlyMangledNames();
|
void testIncorrectlyMangledNames();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void testCorrectlyMangledName(const QString &mangledName,
|
|
||||||
const QString &demangledName);
|
|
||||||
void testIncorrectlyMangledName(const QString &mangledName);
|
void testIncorrectlyMangledName(const QString &mangledName);
|
||||||
NameDemangler demangler;
|
NameDemangler demangler;
|
||||||
};
|
};
|
||||||
@@ -56,131 +62,365 @@ void NameDemanglerAutoTest::testUnmangledName()
|
|||||||
QVERIFY(demangler.demangle("f") && demangler.demangledName() == "f");
|
QVERIFY(demangler.demangle("f") && demangler.demangledName() == "f");
|
||||||
}
|
}
|
||||||
|
|
||||||
void NameDemanglerAutoTest::testCorrectlyMangledNames()
|
void NameDemanglerAutoTest::TEST_CORRECTLY_MANGLED_NAMEs()
|
||||||
{
|
{
|
||||||
testCorrectlyMangledName("_Z1fv", "f()");
|
TEST_CORRECTLY_MANGLED_NAME("_Z1fv", "f()");
|
||||||
testCorrectlyMangledName("_Z1fi", "f(int)");
|
TEST_CORRECTLY_MANGLED_NAME("_Z1fi", "f(int)");
|
||||||
testCorrectlyMangledName("_Z3foo3bar", "foo(bar)");
|
TEST_CORRECTLY_MANGLED_NAME("_Z3foo3bar", "foo(bar)");
|
||||||
testCorrectlyMangledName("_Zrm1XS_", "operator%(X, X)");
|
TEST_CORRECTLY_MANGLED_NAME("_Zrm1XS_", "operator%(X, X)");
|
||||||
testCorrectlyMangledName("_ZplR1XS0_", "operator+(X &, X &)");
|
TEST_CORRECTLY_MANGLED_NAME("_ZplR1XS0_", "operator+(X &, X &)");
|
||||||
testCorrectlyMangledName("_ZlsRK1XS1_", "operator<<(X const &, X const &)");
|
TEST_CORRECTLY_MANGLED_NAME("_ZlsRK1XS1_", "operator<<(X const &, X const &)");
|
||||||
testCorrectlyMangledName("_ZN3FooIA4_iE3barE", "Foo<int[4]>::bar");
|
TEST_CORRECTLY_MANGLED_NAME("_ZN3FooIA4_iE3barE", "Foo<int[4]>::bar");
|
||||||
testCorrectlyMangledName("_Z1fIiEvi", "void f<int>(int)");
|
TEST_CORRECTLY_MANGLED_NAME("_Z1fIiEvi", "void f<int>(int)");
|
||||||
testCorrectlyMangledName("_Z5firstI3DuoEvS0_", "void first<Duo>(Duo)");
|
TEST_CORRECTLY_MANGLED_NAME("_Z5firstI3DuoEvS0_", "void first<Duo>(Duo)");
|
||||||
testCorrectlyMangledName("_Z5firstI3DuoEvT_", "void first<Duo>(Duo)");
|
TEST_CORRECTLY_MANGLED_NAME("_Z5firstI3DuoEvT_", "void first<Duo>(Duo)");
|
||||||
testCorrectlyMangledName("_Z3fooIiPFidEiEvv",
|
TEST_CORRECTLY_MANGLED_NAME("_Z3fooIiPFidEiEvv",
|
||||||
"void foo<int, int (*)(double), int>()");
|
"void foo<int, int (*)(double), int>()");
|
||||||
testCorrectlyMangledName("_ZN1N1fE", "N::f");
|
TEST_CORRECTLY_MANGLED_NAME("_ZN1N1fE", "N::f");
|
||||||
testCorrectlyMangledName("_ZN6System5Sound4beepEv",
|
TEST_CORRECTLY_MANGLED_NAME("_ZN6System5Sound4beepEv",
|
||||||
"System::Sound::beep()");
|
"System::Sound::beep()");
|
||||||
testCorrectlyMangledName("_ZN5Arena5levelE", "Arena::level");
|
TEST_CORRECTLY_MANGLED_NAME("_ZN5Arena5levelE", "Arena::level");
|
||||||
testCorrectlyMangledName("_ZN5StackIiiE5levelE", "Stack<int, int>::level");
|
TEST_CORRECTLY_MANGLED_NAME("_ZN5StackIiiE5levelE", "Stack<int, int>::level");
|
||||||
testCorrectlyMangledName("_Z1fI1XEvPVN1AIT_E1TE",
|
TEST_CORRECTLY_MANGLED_NAME("_Z1fI1XEvPVN1AIT_E1TE",
|
||||||
"void f<X>(A<X>::T volatile *)");
|
"void f<X>(A<X>::T volatile *)");
|
||||||
testCorrectlyMangledName("_ZngILi42EEvN1AIXplT_Li2EEE1TE",
|
TEST_CORRECTLY_MANGLED_NAME("_ZngILi42EEvN1AIXplT_Li2EEE1TE",
|
||||||
"void operator-<42>(A<42 + 2>::T)");
|
"void operator-<42>(A<42 + 2>::T)");
|
||||||
testCorrectlyMangledName("_Z4makeI7FactoryiET_IT0_Ev",
|
TEST_CORRECTLY_MANGLED_NAME("_Z4makeI7FactoryiET_IT0_Ev",
|
||||||
"Factory<int> make<Factory, int>()");
|
"Factory<int> make<Factory, int>()");
|
||||||
testCorrectlyMangledName("_Z3foo5Hello5WorldS0_S_",
|
TEST_CORRECTLY_MANGLED_NAME("_Z3foo5Hello5WorldS0_S_",
|
||||||
"foo(Hello, World, World, Hello)");
|
"foo(Hello, World, World, Hello)");
|
||||||
testCorrectlyMangledName("_Z3fooPM2ABi", "foo(int AB::**)");
|
TEST_CORRECTLY_MANGLED_NAME("_Z3fooPM2ABi", "foo(int AB::**)");
|
||||||
testCorrectlyMangledName("_ZlsRSoRKSs",
|
TEST_CORRECTLY_MANGLED_NAME("_ZlsRSoRKSs",
|
||||||
"operator<<(std::basic_ostream<char, std::char_traits<char> > &, "
|
"operator<<(std::basic_ostream<char, std::char_traits<char> > &, "
|
||||||
"std::basic_string<char, std::char_traits<char>, "
|
"std::basic_string<char, std::char_traits<char>, "
|
||||||
"std::allocator<char> > const &)");
|
"std::allocator<char> > const &)");
|
||||||
testCorrectlyMangledName("_ZTI7a_class", "typeid(a_class)");
|
TEST_CORRECTLY_MANGLED_NAME("_ZTI7a_class", "typeid(a_class)");
|
||||||
testCorrectlyMangledName("_ZZN1A3fooEiE1B", "A::foo(int)::B");
|
TEST_CORRECTLY_MANGLED_NAME("_ZZN1A3fooEiE1B", "A::foo(int)::B");
|
||||||
testCorrectlyMangledName("_ZZ3foovEN1C1DE", "foo()::C::D");
|
TEST_CORRECTLY_MANGLED_NAME("_ZZ3foovEN1C1DE", "foo()::C::D");
|
||||||
testCorrectlyMangledName("_ZZZ3foovEN1C3barEvEN1E3bazEv",
|
TEST_CORRECTLY_MANGLED_NAME("_ZZZ3foovEN1C3barEvEN1E3bazEv",
|
||||||
"foo()::C::bar()::E::baz()");
|
"foo()::C::bar()::E::baz()");
|
||||||
testCorrectlyMangledName("_ZZN1N1fEiE1p", "N::f(int)::p");
|
TEST_CORRECTLY_MANGLED_NAME("_ZZN1N1fEiE1p", "N::f(int)::p");
|
||||||
testCorrectlyMangledName("_ZZN1N1fEiEs", "N::f(int)::\"string literal\"");
|
TEST_CORRECTLY_MANGLED_NAME("_ZZN1N1fEiEs", "N::f(int)::[string literal]");
|
||||||
testCorrectlyMangledName("_Z3fooc", "foo(char)");
|
TEST_CORRECTLY_MANGLED_NAME("_Z3fooc", "foo(char)");
|
||||||
testCorrectlyMangledName("_Z2CBIL_Z3foocEE", "CB<foo(char)>");
|
TEST_CORRECTLY_MANGLED_NAME("_Z2CBIL_Z3foocEE", "CB<foo(char)>");
|
||||||
testCorrectlyMangledName("_Z2CBIL_Z7IsEmptyEE", "CB<IsEmpty>");
|
TEST_CORRECTLY_MANGLED_NAME("_Z2CBIL_Z7IsEmptyEE", "CB<IsEmpty>");
|
||||||
testCorrectlyMangledName("_ZN1N1TIiiE2mfES0_IddE",
|
TEST_CORRECTLY_MANGLED_NAME("_ZN1N1TIiiE2mfES0_IddE",
|
||||||
"N::T<int, int>::mf(N::T<double, double>)");
|
"N::T<int, int>::mf(N::T<double, double>)");
|
||||||
testCorrectlyMangledName("_ZSt5state", "std::state");
|
TEST_CORRECTLY_MANGLED_NAME("_ZSt5state", "std::state");
|
||||||
testCorrectlyMangledName("_ZNSt3_In4wardE", "std::_In::ward");
|
TEST_CORRECTLY_MANGLED_NAME("_ZNSt3_In4wardE", "std::_In::ward");
|
||||||
testCorrectlyMangledName("_Z41__static_initialization_and_destruction_0ii",
|
TEST_CORRECTLY_MANGLED_NAME("_Z41__static_initialization_and_destruction_0ii",
|
||||||
"__static_initialization_and_destruction_0(int, int)");
|
"__static_initialization_and_destruction_0(int, int)");
|
||||||
testCorrectlyMangledName("_ZN20NameDemanglerPrivate3eoiE",
|
TEST_CORRECTLY_MANGLED_NAME("_ZN20NameDemanglerPrivate3eoiE",
|
||||||
"NameDemanglerPrivate::eoi");
|
"NameDemanglerPrivate::eoi");
|
||||||
testCorrectlyMangledName(
|
TEST_CORRECTLY_MANGLED_NAME(
|
||||||
"_ZZN20NameDemanglerPrivate15parseIdentifierEiE8__func__",
|
"_ZZN20NameDemanglerPrivate15parseIdentifierEiE8__func__",
|
||||||
"NameDemanglerPrivate::parseIdentifier(int)::__func__");
|
"NameDemanglerPrivate::parseIdentifier(int)::__func__");
|
||||||
testCorrectlyMangledName("_ZN4QSetI5QCharED1Ev", "QSet<QChar>::~QSet()");
|
TEST_CORRECTLY_MANGLED_NAME("_ZN4QSetI5QCharED1Ev", "QSet<QChar>::~QSet()");
|
||||||
testCorrectlyMangledName("_Zne5QCharS_", "operator!=(QChar, QChar)");
|
TEST_CORRECTLY_MANGLED_NAME("_Zne5QCharS_", "operator!=(QChar, QChar)");
|
||||||
testCorrectlyMangledName("_ZN20NameDemanglerPrivate17parseFunctionTypeEv",
|
TEST_CORRECTLY_MANGLED_NAME("_ZN20NameDemanglerPrivate17parseFunctionTypeEv",
|
||||||
"NameDemanglerPrivate::parseFunctionType()");
|
"NameDemanglerPrivate::parseFunctionType()");
|
||||||
testCorrectlyMangledName(
|
TEST_CORRECTLY_MANGLED_NAME(
|
||||||
"_ZNK20NameDemanglerPrivate16ArrayNewOperator8makeExprERK11QStringList",
|
"_ZNK20NameDemanglerPrivate16ArrayNewOperator8makeExprERK11QStringList",
|
||||||
"NameDemanglerPrivate::ArrayNewOperator::makeExpr(QStringList const &) const");
|
"NameDemanglerPrivate::ArrayNewOperator::makeExpr(QStringList const &) const");
|
||||||
testCorrectlyMangledName("_ZN13QLatin1StringC1EPKc",
|
TEST_CORRECTLY_MANGLED_NAME("_ZN13QLatin1StringC1EPKc",
|
||||||
"QLatin1String::QLatin1String(char const *)");
|
"QLatin1String::QLatin1String(char const *)");
|
||||||
testCorrectlyMangledName(
|
TEST_CORRECTLY_MANGLED_NAME(
|
||||||
"_ZN15QtSharedPointer16ExternalRefCountIN20NameDemanglerPrivate8OperatorEE12internalCopyIS2_EEvRKNS0_IT_EE",
|
"_ZN15QtSharedPointer16ExternalRefCountIN20NameDemanglerPrivate8OperatorEE12internalCopyIS2_EEvRKNS0_IT_EE",
|
||||||
"void QtSharedPointer::ExternalRefCount<NameDemanglerPrivate::Operator>::internalCopy<NameDemanglerPrivate::Operator>(QtSharedPointer::ExternalRefCount<NameDemanglerPrivate::Operator> const &)");
|
"void QtSharedPointer::ExternalRefCount<NameDemanglerPrivate::Operator>::internalCopy<NameDemanglerPrivate::Operator>(QtSharedPointer::ExternalRefCount<NameDemanglerPrivate::Operator> const &)");
|
||||||
testCorrectlyMangledName(
|
TEST_CORRECTLY_MANGLED_NAME(
|
||||||
"_ZN15QtSharedPointer16ExternalRefCountIN20NameDemanglerPrivate8OperatorEE11internalSetEPNS_20ExternalRefCountDataEPS2_",
|
"_ZN15QtSharedPointer16ExternalRefCountIN20NameDemanglerPrivate8OperatorEE11internalSetEPNS_20ExternalRefCountDataEPS2_",
|
||||||
"QtSharedPointer::ExternalRefCount<NameDemanglerPrivate::Operator>::internalSet(QtSharedPointer::ExternalRefCountData *, NameDemanglerPrivate::Operator *)");
|
"QtSharedPointer::ExternalRefCount<NameDemanglerPrivate::Operator>::internalSet(QtSharedPointer::ExternalRefCountData *, NameDemanglerPrivate::Operator *)");
|
||||||
testCorrectlyMangledName("_ZN20NameDemanglerPrivate17parseUnscopedNameEv",
|
TEST_CORRECTLY_MANGLED_NAME("_ZN20NameDemanglerPrivate17parseUnscopedNameEv",
|
||||||
"NameDemanglerPrivate::parseUnscopedName()");
|
"NameDemanglerPrivate::parseUnscopedName()");
|
||||||
testCorrectlyMangledName("_ZNK7QString3argExiiRK5QChar",
|
TEST_CORRECTLY_MANGLED_NAME("_ZNK7QString3argExiiRK5QChar",
|
||||||
"QString::arg(long long, int, int, QChar const &) const");
|
"QString::arg(long long, int, int, QChar const &) const");
|
||||||
testCorrectlyMangledName(
|
TEST_CORRECTLY_MANGLED_NAME(
|
||||||
"_ZN20NameDemanglerPrivate8OperatorC2ERK7QStringS3_",
|
"_ZN20NameDemanglerPrivate8OperatorC2ERK7QStringS3_",
|
||||||
"NameDemanglerPrivate::Operator::Operator(QString const &, QString const &)");
|
"NameDemanglerPrivate::Operator::Operator(QString const &, QString const &)");
|
||||||
testCorrectlyMangledName(
|
TEST_CORRECTLY_MANGLED_NAME(
|
||||||
"_ZN15QtSharedPointer16ExternalRefCountIN20NameDemanglerPrivate8OperatorEEC2EN2Qt14InitializationE",
|
"_ZN15QtSharedPointer16ExternalRefCountIN20NameDemanglerPrivate8OperatorEEC2EN2Qt14InitializationE",
|
||||||
"QtSharedPointer::ExternalRefCount<NameDemanglerPrivate::Operator>::ExternalRefCount(Qt::Initialization)");
|
"QtSharedPointer::ExternalRefCount<NameDemanglerPrivate::Operator>::ExternalRefCount(Qt::Initialization)");
|
||||||
testCorrectlyMangledName("_ZN7QString5clearEv", "QString::clear()");
|
TEST_CORRECTLY_MANGLED_NAME("_ZN7QString5clearEv", "QString::clear()");
|
||||||
testCorrectlyMangledName("_ZNK5QListI7QStringE2atEi",
|
TEST_CORRECTLY_MANGLED_NAME("_ZNK5QListI7QStringE2atEi",
|
||||||
"QList<QString>::at(int) const");
|
"QList<QString>::at(int) const");
|
||||||
testCorrectlyMangledName(
|
TEST_CORRECTLY_MANGLED_NAME(
|
||||||
"_ZNK7QString10startsWithERKS_N2Qt15CaseSensitivityE",
|
"_ZNK7QString10startsWithERKS_N2Qt15CaseSensitivityE",
|
||||||
"QString::startsWith(QString const &, Qt::CaseSensitivity) const");
|
"QString::startsWith(QString const &, Qt::CaseSensitivity) const");
|
||||||
testCorrectlyMangledName("_ZNK4QSetI5QCharE8constEndEv",
|
TEST_CORRECTLY_MANGLED_NAME("_ZNK4QSetI5QCharE8constEndEv",
|
||||||
"QSet<QChar>::constEnd() const");
|
"QSet<QChar>::constEnd() const");
|
||||||
testCorrectlyMangledName("_Z11qt_assert_xPKcS0_S0_i",
|
TEST_CORRECTLY_MANGLED_NAME("_Z11qt_assert_xPKcS0_S0_i",
|
||||||
"qt_assert_x(char const *, char const *, char const *, int)");
|
"qt_assert_x(char const *, char const *, char const *, int)");
|
||||||
testCorrectlyMangledName("_ZN9QHashData8willGrowEv",
|
TEST_CORRECTLY_MANGLED_NAME("_ZN9QHashData8willGrowEv",
|
||||||
"QHashData::willGrow()");
|
"QHashData::willGrow()");
|
||||||
testCorrectlyMangledName(
|
TEST_CORRECTLY_MANGLED_NAME(
|
||||||
"_ZNK5QHashI5QChar15QHashDummyValueE14const_iteratorneERKS3_",
|
"_ZNK5QHashI5QChar15QHashDummyValueE14const_iteratorneERKS3_",
|
||||||
"QHash<QChar, QHashDummyValue>::const_iterator::operator!=(QHash<QChar, QHashDummyValue>::const_iterator const &) const");
|
"QHash<QChar, QHashDummyValue>::const_iterator::operator!=(QHash<QChar, QHashDummyValue>::const_iterator const &) const");
|
||||||
testCorrectlyMangledName("_ZNK13NameDemangler11errorStringEv",
|
TEST_CORRECTLY_MANGLED_NAME("_ZNK13NameDemangler11errorStringEv",
|
||||||
"NameDemangler::errorString() const");
|
"NameDemangler::errorString() const");
|
||||||
testCorrectlyMangledName("_ZN7QString7replaceERK7QRegExpRKS_",
|
TEST_CORRECTLY_MANGLED_NAME("_ZN7QString7replaceERK7QRegExpRKS_",
|
||||||
"QString::replace(QRegExp const &, QString const &)");
|
"QString::replace(QRegExp const &, QString const &)");
|
||||||
testCorrectlyMangledName("_ZN7QString4freeEPNS_4DataE",
|
TEST_CORRECTLY_MANGLED_NAME("_ZN7QString4freeEPNS_4DataE",
|
||||||
"QString::free(QString::Data *)");
|
"QString::free(QString::Data *)");
|
||||||
testCorrectlyMangledName(
|
TEST_CORRECTLY_MANGLED_NAME(
|
||||||
"_ZTSN20NameDemanglerPrivate19ArrayAccessOperatorE",
|
"_ZTSN20NameDemanglerPrivate19ArrayAccessOperatorE",
|
||||||
"typeid(NameDemanglerPrivate::ArrayAccessOperator).name()");
|
"typeid(NameDemanglerPrivate::ArrayAccessOperator).name()");
|
||||||
testCorrectlyMangledName("_ZN3ns11fERKPFPKiS1_RKhE",
|
TEST_CORRECTLY_MANGLED_NAME("_ZN3ns11fERKPFPKiS1_RKhE",
|
||||||
"ns1::f(int const * (* const &)(int const *, unsigned char const &))");
|
"ns1::f(int const * (* const &)(int const *, unsigned char const &))");
|
||||||
testCorrectlyMangledName("_Z9test_funcMN3ns11cImEEKFPKvPiRlmE",
|
TEST_CORRECTLY_MANGLED_NAME("_Z9test_funcMN3ns11cImEEKFPKvPiRlmE",
|
||||||
"test_func(void const * (ns1::c<unsigned long>::*)(int *, long &, unsigned long) const)");
|
"test_func(void const * (ns1::c<unsigned long>::*)(int *, long &, unsigned long) const)");
|
||||||
testCorrectlyMangledName("_ZN3ns11fEPKPFPKiS1_RKhE",
|
TEST_CORRECTLY_MANGLED_NAME("_ZN3ns11fEPKPFPKiS1_RKhE",
|
||||||
"ns1::f(int const * (* const *)(int const *, unsigned char const &))");
|
"ns1::f(int const * (* const *)(int const *, unsigned char const &))");
|
||||||
testCorrectlyMangledName("_ZNK1CcviEv", "C::operator int() const");
|
TEST_CORRECTLY_MANGLED_NAME("_ZNK1CcviEv", "C::operator int() const");
|
||||||
testCorrectlyMangledName("_ZN1CppEv", "C::operator++()");
|
TEST_CORRECTLY_MANGLED_NAME("_ZN1CppEv", "C::operator++()");
|
||||||
testCorrectlyMangledName("_ZN1CmmEv", "C::operator--()");
|
TEST_CORRECTLY_MANGLED_NAME("_ZN1CmmEv", "C::operator--()");
|
||||||
testCorrectlyMangledName("_ZN1CppEi", "C::operator++(int)");
|
TEST_CORRECTLY_MANGLED_NAME("_ZN1CppEi", "C::operator++(int)");
|
||||||
testCorrectlyMangledName("_ZN1CmmEi", "C::operator--(int)");
|
TEST_CORRECTLY_MANGLED_NAME("_ZN1CmmEi", "C::operator--(int)");
|
||||||
testCorrectlyMangledName("_ZNK1CcvT_IPKcEEv", "C::operator char const *<char const *>() const");
|
TEST_CORRECTLY_MANGLED_NAME("_ZNK1CcvT_IPKcEEv", "C::operator char const *<char const *>() const");
|
||||||
}
|
}
|
||||||
|
|
||||||
void NameDemanglerAutoTest::testIncorrectlyMangledNames()
|
void NameDemanglerAutoTest::testIncorrectlyMangledNames()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void NameDemanglerAutoTest::testCorrectlyMangledName(
|
void NameDemanglerAutoTest::testDisjunctFirstSets()
|
||||||
const QString &mangledName, const QString &demangledName)
|
|
||||||
{
|
{
|
||||||
demangler.demangle(mangledName);
|
for (char c = 0x20; c < 0x7e; ++c) {
|
||||||
QCOMPARE(demangler.demangledName(), demangledName);
|
|
||||||
|
// <encoding>
|
||||||
|
QVERIFY(!NameNode::mangledRepresentationStartsWith(c)
|
||||||
|
|| !SpecialNameNode::mangledRepresentationStartsWith(c));
|
||||||
|
|
||||||
|
// <name>
|
||||||
|
QVERIFY(!NestedNameNode::mangledRepresentationStartsWith(c)
|
||||||
|
|| !UnscopedNameNode::mangledRepresentationStartsWith(c));
|
||||||
|
QVERIFY(!NestedNameNode::mangledRepresentationStartsWith(c)
|
||||||
|
|| !SubstitutionNode::mangledRepresentationStartsWith(c));
|
||||||
|
QVERIFY(!NestedNameNode::mangledRepresentationStartsWith(c)
|
||||||
|
|| !LocalNameNode::mangledRepresentationStartsWith(c));
|
||||||
|
QVERIFY(!UnscopedNameNode::mangledRepresentationStartsWith(c)
|
||||||
|
|| !SubstitutionNode::mangledRepresentationStartsWith(c) || c == 'S');
|
||||||
|
QVERIFY(!UnscopedNameNode::mangledRepresentationStartsWith(c)
|
||||||
|
|| !LocalNameNode::mangledRepresentationStartsWith(c));
|
||||||
|
QVERIFY(!SubstitutionNode::mangledRepresentationStartsWith(c)
|
||||||
|
|| !LocalNameNode::mangledRepresentationStartsWith(c));
|
||||||
|
|
||||||
|
// <nested-name>
|
||||||
|
QVERIFY(!CvQualifiersNode::mangledRepresentationStartsWith(c)
|
||||||
|
|| !PrefixNode::mangledRepresentationStartsWith(c) || c == 'r');
|
||||||
|
|
||||||
|
// <prefix>
|
||||||
|
QVERIFY(!TemplateParamNode::mangledRepresentationStartsWith(c)
|
||||||
|
|| !SubstitutionNode::mangledRepresentationStartsWith(c));
|
||||||
|
QVERIFY(!TemplateArgsNode::mangledRepresentationStartsWith(c)
|
||||||
|
|| !Prefix2Node::mangledRepresentationStartsWith(c));
|
||||||
|
QVERIFY(!TemplateParamNode::mangledRepresentationStartsWith(c)
|
||||||
|
|| !Prefix2Node::mangledRepresentationStartsWith(c));
|
||||||
|
QVERIFY(!SubstitutionNode::mangledRepresentationStartsWith(c)
|
||||||
|
|| !Prefix2Node::mangledRepresentationStartsWith(c));
|
||||||
|
|
||||||
|
// <prefix2>
|
||||||
|
QVERIFY(!TemplateArgsNode::mangledRepresentationStartsWith(c)
|
||||||
|
|| !Prefix2Node::mangledRepresentationStartsWith(c));
|
||||||
|
|
||||||
|
|
||||||
|
// <template-arg>
|
||||||
|
QVERIFY(!TypeNode::mangledRepresentationStartsWith(c)
|
||||||
|
|| !ExprPrimaryNode::mangledRepresentationStartsWith(c));
|
||||||
|
|
||||||
|
// <expression>
|
||||||
|
QVERIFY(!OperatorNameNode::mangledRepresentationStartsWith(c)
|
||||||
|
|| !TemplateParamNode::mangledRepresentationStartsWith(c));
|
||||||
|
// QVERIFY(!OperatorNameNode::mangledRepresentationStartsWith(c)
|
||||||
|
// || !FunctionParamNode::mangledRepresentationStartsWith(c))
|
||||||
|
QVERIFY(!OperatorNameNode::mangledRepresentationStartsWith(c)
|
||||||
|
|| !ExprPrimaryNode::mangledRepresentationStartsWith(c));
|
||||||
|
// QVERIFY(!TemplateParamNode::mangledRepresentationStartsWith(c)
|
||||||
|
// || !FunctionParamNode::mangledRepresentationStartsWith(c));
|
||||||
|
QVERIFY(!TemplateParamNode::mangledRepresentationStartsWith(c)
|
||||||
|
|| !ExprPrimaryNode::mangledRepresentationStartsWith(c));
|
||||||
|
// QVERIFY(!FunctionParamNode::mangledRepresentationStartsWith(c)
|
||||||
|
// || !ExprPrimaryNode::mangledRepresentationStartsWith(c));
|
||||||
|
|
||||||
|
// <expr-primary>
|
||||||
|
QVERIFY(!TypeNode::mangledRepresentationStartsWith(c)
|
||||||
|
|| !MangledNameNode::mangledRepresentationStartsWith(c));
|
||||||
|
|
||||||
|
// <type>
|
||||||
|
QVERIFY(!BuiltinTypeNode::mangledRepresentationStartsWith(c)
|
||||||
|
|| !FunctionTypeNode::mangledRepresentationStartsWith(c));
|
||||||
|
|
||||||
|
QVERIFY2(!BuiltinTypeNode::mangledRepresentationStartsWith(c)
|
||||||
|
|| !ClassEnumTypeNode::mangledRepresentationStartsWith(c) || c == 'D', &c);
|
||||||
|
QVERIFY(!BuiltinTypeNode::mangledRepresentationStartsWith(c)
|
||||||
|
|| !ArrayTypeNode::mangledRepresentationStartsWith(c));
|
||||||
|
QVERIFY(!BuiltinTypeNode::mangledRepresentationStartsWith(c)
|
||||||
|
|| !PointerToMemberTypeNode::mangledRepresentationStartsWith(c));
|
||||||
|
QVERIFY(!BuiltinTypeNode::mangledRepresentationStartsWith(c)
|
||||||
|
|| !TemplateParamNode::mangledRepresentationStartsWith(c));
|
||||||
|
QVERIFY(!BuiltinTypeNode::mangledRepresentationStartsWith(c)
|
||||||
|
|| !SubstitutionNode::mangledRepresentationStartsWith(c));
|
||||||
|
QVERIFY(!BuiltinTypeNode::mangledRepresentationStartsWith(c)
|
||||||
|
|| !CvQualifiersNode::mangledRepresentationStartsWith(c));
|
||||||
|
QVERIFY(!FunctionTypeNode::mangledRepresentationStartsWith(c)
|
||||||
|
|| !ClassEnumTypeNode::mangledRepresentationStartsWith(c));
|
||||||
|
QVERIFY(!FunctionTypeNode::mangledRepresentationStartsWith(c)
|
||||||
|
|| !ArrayTypeNode::mangledRepresentationStartsWith(c));
|
||||||
|
QVERIFY(!FunctionTypeNode::mangledRepresentationStartsWith(c)
|
||||||
|
|| !PointerToMemberTypeNode::mangledRepresentationStartsWith(c));
|
||||||
|
QVERIFY(!FunctionTypeNode::mangledRepresentationStartsWith(c)
|
||||||
|
|| !TemplateParamNode::mangledRepresentationStartsWith(c));
|
||||||
|
QVERIFY(!FunctionTypeNode::mangledRepresentationStartsWith(c)
|
||||||
|
|| !SubstitutionNode::mangledRepresentationStartsWith(c));
|
||||||
|
QVERIFY(!FunctionTypeNode::mangledRepresentationStartsWith(c)
|
||||||
|
|| !CvQualifiersNode::mangledRepresentationStartsWith(c));
|
||||||
|
QVERIFY(!ClassEnumTypeNode::mangledRepresentationStartsWith(c)
|
||||||
|
|| !ArrayTypeNode::mangledRepresentationStartsWith(c));
|
||||||
|
QVERIFY(!ClassEnumTypeNode::mangledRepresentationStartsWith(c)
|
||||||
|
|| !PointerToMemberTypeNode::mangledRepresentationStartsWith(c));
|
||||||
|
QVERIFY(!ClassEnumTypeNode::mangledRepresentationStartsWith(c)
|
||||||
|
|| !TemplateParamNode::mangledRepresentationStartsWith(c));
|
||||||
|
QVERIFY(!ClassEnumTypeNode::mangledRepresentationStartsWith(c)
|
||||||
|
|| !SubstitutionNode::mangledRepresentationStartsWith(c));
|
||||||
|
QVERIFY(!ClassEnumTypeNode::mangledRepresentationStartsWith(c)
|
||||||
|
|| !CvQualifiersNode::mangledRepresentationStartsWith(c));
|
||||||
|
QVERIFY(!ArrayTypeNode::mangledRepresentationStartsWith(c)
|
||||||
|
|| !PointerToMemberTypeNode::mangledRepresentationStartsWith(c));
|
||||||
|
QVERIFY(!ArrayTypeNode::mangledRepresentationStartsWith(c)
|
||||||
|
|| !TemplateParamNode::mangledRepresentationStartsWith(c));
|
||||||
|
QVERIFY(!ArrayTypeNode::mangledRepresentationStartsWith(c)
|
||||||
|
|| !SubstitutionNode::mangledRepresentationStartsWith(c));
|
||||||
|
QVERIFY(!ArrayTypeNode::mangledRepresentationStartsWith(c)
|
||||||
|
|| !CvQualifiersNode::mangledRepresentationStartsWith(c));
|
||||||
|
QVERIFY(!PointerToMemberTypeNode::mangledRepresentationStartsWith(c)
|
||||||
|
|| !TemplateParamNode::mangledRepresentationStartsWith(c));
|
||||||
|
QVERIFY(!PointerToMemberTypeNode::mangledRepresentationStartsWith(c)
|
||||||
|
|| !SubstitutionNode::mangledRepresentationStartsWith(c));
|
||||||
|
QVERIFY(!PointerToMemberTypeNode::mangledRepresentationStartsWith(c)
|
||||||
|
|| !CvQualifiersNode::mangledRepresentationStartsWith(c));
|
||||||
|
QVERIFY(!TemplateParamNode::mangledRepresentationStartsWith(c)
|
||||||
|
|| !SubstitutionNode::mangledRepresentationStartsWith(c));
|
||||||
|
QVERIFY(!TemplateParamNode::mangledRepresentationStartsWith(c)
|
||||||
|
|| !CvQualifiersNode::mangledRepresentationStartsWith(c));
|
||||||
|
QVERIFY(!SubstitutionNode::mangledRepresentationStartsWith(c)
|
||||||
|
|| !CvQualifiersNode::mangledRepresentationStartsWith(c));
|
||||||
|
|
||||||
|
// <unqualified-name>
|
||||||
|
QVERIFY(!OperatorNameNode::mangledRepresentationStartsWith(c)
|
||||||
|
|| !CtorDtorNameNode::mangledRepresentationStartsWith(c));
|
||||||
|
QVERIFY(!OperatorNameNode::mangledRepresentationStartsWith(c)
|
||||||
|
|| !SourceNameNode::mangledRepresentationStartsWith(c));
|
||||||
|
QVERIFY(!CtorDtorNameNode::mangledRepresentationStartsWith(c)
|
||||||
|
|| !SourceNameNode::mangledRepresentationStartsWith(c));
|
||||||
|
|
||||||
|
// <array-type>
|
||||||
|
QVERIFY(!NonNegativeNumberNode::mangledRepresentationStartsWith(c)
|
||||||
|
|| !ExpressionNode::mangledRepresentationStartsWith(c));
|
||||||
|
}
|
||||||
|
|
||||||
|
// <template-args>, <template-arg>
|
||||||
|
QVERIFY(!TemplateArgNode::mangledRepresentationStartsWith('E'));
|
||||||
|
|
||||||
|
// <template-arg>
|
||||||
|
QVERIFY(!TypeNode::mangledRepresentationStartsWith('X')
|
||||||
|
&& !TypeNode::mangledRepresentationStartsWith('J')
|
||||||
|
/* && !TypeNode::mangledRepresentationStartsWith('s') */);
|
||||||
|
QVERIFY(!ExprPrimaryNode::mangledRepresentationStartsWith('X')
|
||||||
|
&& !ExprPrimaryNode::mangledRepresentationStartsWith('J')
|
||||||
|
&& !ExprPrimaryNode::mangledRepresentationStartsWith('s'));
|
||||||
|
|
||||||
|
// <expression>
|
||||||
|
QVERIFY(!TemplateParamNode::mangledRepresentationStartsWith('c')
|
||||||
|
&& !TemplateParamNode::mangledRepresentationStartsWith('s')
|
||||||
|
&& !TemplateParamNode::mangledRepresentationStartsWith('a'));
|
||||||
|
// QVERIFY(!FunctionParamNode::mangledRepresentationStartsWith('c')
|
||||||
|
// && !FunctionParamNode::mangledRepresentationStartsWith('c')
|
||||||
|
// && !FunctionParamNode::mangledRepresentationStartsWith('c'));
|
||||||
|
QVERIFY(!ExprPrimaryNode::mangledRepresentationStartsWith('c')
|
||||||
|
&& !ExprPrimaryNode::mangledRepresentationStartsWith('s')
|
||||||
|
&& !ExprPrimaryNode::mangledRepresentationStartsWith('a'));
|
||||||
|
QVERIFY(!ExpressionNode::mangledRepresentationStartsWith('E'));
|
||||||
|
QVERIFY(!ExpressionNode::mangledRepresentationStartsWith('_'));
|
||||||
|
|
||||||
|
// <type>
|
||||||
|
QVERIFY(!BuiltinTypeNode::mangledRepresentationStartsWith('P')
|
||||||
|
&& !BuiltinTypeNode::mangledRepresentationStartsWith('R')
|
||||||
|
&& !BuiltinTypeNode::mangledRepresentationStartsWith('O')
|
||||||
|
&& !BuiltinTypeNode::mangledRepresentationStartsWith('C')
|
||||||
|
&& !BuiltinTypeNode::mangledRepresentationStartsWith('G')
|
||||||
|
&& !BuiltinTypeNode::mangledRepresentationStartsWith('U'));
|
||||||
|
QVERIFY(!FunctionTypeNode::mangledRepresentationStartsWith('P')
|
||||||
|
&& !FunctionTypeNode::mangledRepresentationStartsWith('R')
|
||||||
|
&& !FunctionTypeNode::mangledRepresentationStartsWith('O')
|
||||||
|
&& !FunctionTypeNode::mangledRepresentationStartsWith('C')
|
||||||
|
&& !FunctionTypeNode::mangledRepresentationStartsWith('G')
|
||||||
|
&& !FunctionTypeNode::mangledRepresentationStartsWith('U')
|
||||||
|
&& !FunctionTypeNode::mangledRepresentationStartsWith('D'));
|
||||||
|
QVERIFY(!ClassEnumTypeNode::mangledRepresentationStartsWith('P')
|
||||||
|
&& !ClassEnumTypeNode::mangledRepresentationStartsWith('R')
|
||||||
|
&& !ClassEnumTypeNode::mangledRepresentationStartsWith('O')
|
||||||
|
&& !ClassEnumTypeNode::mangledRepresentationStartsWith('C')
|
||||||
|
&& !ClassEnumTypeNode::mangledRepresentationStartsWith('G')
|
||||||
|
&& !ClassEnumTypeNode::mangledRepresentationStartsWith('U')
|
||||||
|
/* && !firstSetClassEnumType.contains('D') */);
|
||||||
|
QVERIFY(!ArrayTypeNode::mangledRepresentationStartsWith('P')
|
||||||
|
&& !ArrayTypeNode::mangledRepresentationStartsWith('R')
|
||||||
|
&& !ArrayTypeNode::mangledRepresentationStartsWith('O')
|
||||||
|
&& !ArrayTypeNode::mangledRepresentationStartsWith('C')
|
||||||
|
&& !ArrayTypeNode::mangledRepresentationStartsWith('G')
|
||||||
|
&& !ArrayTypeNode::mangledRepresentationStartsWith('U')
|
||||||
|
&& !ArrayTypeNode::mangledRepresentationStartsWith('D'));
|
||||||
|
QVERIFY(!PointerToMemberTypeNode::mangledRepresentationStartsWith('P')
|
||||||
|
&& !PointerToMemberTypeNode::mangledRepresentationStartsWith('R')
|
||||||
|
&& !PointerToMemberTypeNode::mangledRepresentationStartsWith('O')
|
||||||
|
&& !PointerToMemberTypeNode::mangledRepresentationStartsWith('C')
|
||||||
|
&& !PointerToMemberTypeNode::mangledRepresentationStartsWith('G')
|
||||||
|
&& !PointerToMemberTypeNode::mangledRepresentationStartsWith('U')
|
||||||
|
&& !PointerToMemberTypeNode::mangledRepresentationStartsWith('D'));
|
||||||
|
QVERIFY(!TemplateParamNode::mangledRepresentationStartsWith('P')
|
||||||
|
&& !TemplateParamNode::mangledRepresentationStartsWith('R')
|
||||||
|
&& !TemplateParamNode::mangledRepresentationStartsWith('O')
|
||||||
|
&& !TemplateParamNode::mangledRepresentationStartsWith('C')
|
||||||
|
&& !TemplateParamNode::mangledRepresentationStartsWith('G')
|
||||||
|
&& !TemplateParamNode::mangledRepresentationStartsWith('U')
|
||||||
|
&& !TemplateParamNode::mangledRepresentationStartsWith('D'));
|
||||||
|
QVERIFY(!SubstitutionNode::mangledRepresentationStartsWith('P')
|
||||||
|
&& !SubstitutionNode::mangledRepresentationStartsWith('R')
|
||||||
|
&& !SubstitutionNode::mangledRepresentationStartsWith('O')
|
||||||
|
&& !SubstitutionNode::mangledRepresentationStartsWith('C')
|
||||||
|
&& !SubstitutionNode::mangledRepresentationStartsWith('G')
|
||||||
|
&& !SubstitutionNode::mangledRepresentationStartsWith('U')
|
||||||
|
&& !SubstitutionNode::mangledRepresentationStartsWith('D'));
|
||||||
|
QVERIFY(!CvQualifiersNode::mangledRepresentationStartsWith('P')
|
||||||
|
&& !CvQualifiersNode::mangledRepresentationStartsWith('R')
|
||||||
|
&& !CvQualifiersNode::mangledRepresentationStartsWith('O')
|
||||||
|
&& !CvQualifiersNode::mangledRepresentationStartsWith('C')
|
||||||
|
&& !CvQualifiersNode::mangledRepresentationStartsWith('G')
|
||||||
|
&& !CvQualifiersNode::mangledRepresentationStartsWith('U')
|
||||||
|
&& !CvQualifiersNode::mangledRepresentationStartsWith('D'));
|
||||||
|
|
||||||
|
// <array-type>
|
||||||
|
QVERIFY(!NonNegativeNumberNode::mangledRepresentationStartsWith('_'));
|
||||||
|
QVERIFY(!ExpressionNode::mangledRepresentationStartsWith('_'));
|
||||||
|
|
||||||
|
// <substitution>
|
||||||
|
QVERIFY(!NonNegativeNumberNode::mangledRepresentationStartsWith('_', 36)
|
||||||
|
&& !NonNegativeNumberNode::mangledRepresentationStartsWith('t', 36)
|
||||||
|
&& !NonNegativeNumberNode::mangledRepresentationStartsWith('a', 36)
|
||||||
|
&& !NonNegativeNumberNode::mangledRepresentationStartsWith('b', 36)
|
||||||
|
&& !NonNegativeNumberNode::mangledRepresentationStartsWith('s', 36)
|
||||||
|
&& !NonNegativeNumberNode::mangledRepresentationStartsWith('i', 36)
|
||||||
|
&& !NonNegativeNumberNode::mangledRepresentationStartsWith('o', 36)
|
||||||
|
&& !NonNegativeNumberNode::mangledRepresentationStartsWith('d', 36));
|
||||||
|
|
||||||
|
// <special-name>
|
||||||
|
QVERIFY(!CallOffsetNode::mangledRepresentationStartsWith('V')
|
||||||
|
&& !CallOffsetNode::mangledRepresentationStartsWith('T')
|
||||||
|
&& !CallOffsetNode::mangledRepresentationStartsWith('I')
|
||||||
|
&& !CallOffsetNode::mangledRepresentationStartsWith('S')
|
||||||
|
&& !CallOffsetNode::mangledRepresentationStartsWith('c'));
|
||||||
|
|
||||||
|
// <unscoped-name>
|
||||||
|
QVERIFY(!UnqualifiedNameNode::mangledRepresentationStartsWith('S'));
|
||||||
}
|
}
|
||||||
|
|
||||||
void NameDemanglerAutoTest::testIncorrectlyMangledName(
|
void NameDemanglerAutoTest::testIncorrectlyMangledName(
|
||||||
|
|||||||
Reference in New Issue
Block a user