Commit 96368496 authored by Christian Kandeler's avatar Christian Kandeler
Browse files

Debugger: Refactor name demangler.



Now all the parsing logic as well as the stringification is in the tree
nodes.

Change-Id: Ie8222729c14c0102d94045026fc61a75cd31cc63
Reviewed-by: default avatarChristian Kandeler <christian.kandeler@nokia.com>
parent 91d22556
......@@ -265,7 +265,9 @@ QtcPlugin {
"namedemangler/namedemangler.h",
"namedemangler/parsetreenodes.cpp",
"namedemangler/parsetreenodes.h",
"namedemangler/demanglerexceptions.h"
"namedemangler/demanglerexceptions.h",
"namedemangler/globalparsestate.h",
"namedemangler/globalparsestate.cpp"
]
Group {
......
/**************************************************************************
**
** 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 "globalparsestate.h"
#include "demanglerexceptions.h"
#include "parsetreenodes.h"
namespace Debugger {
namespace Internal {
char GlobalParseState::peek(int ahead)
{
Q_ASSERT(m_pos >= 0);
if (m_pos + ahead < m_mangledName.size())
return m_mangledName[m_pos + ahead];
return eoi;
}
char GlobalParseState::advance(int steps)
{
Q_ASSERT(steps > 0);
if (m_pos + steps > m_mangledName.size())
throw ParseException(QLatin1String("Unexpected end of input"));
const char c = m_mangledName[m_pos];
m_pos += steps;
return c;
}
QByteArray GlobalParseState::readAhead(int charCount) const
{
QByteArray str;
if (m_pos + charCount <= m_mangledName.size())
str = m_mangledName.mid(m_pos, charCount);
else
str.fill(eoi, charCount);
return str;
}
void GlobalParseState::addSubstitution(const ParseTreeNode *node)
{
const QByteArray symbol = node->toByteArray();
if (!symbol.isEmpty() && !m_substitutions.contains(symbol))
m_substitutions.append(symbol);
}
} // namespace Internal
} // namespace Debugger
/**************************************************************************
**
** 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 GLOBAL_PARSE_STATE_H
#define GLOBAL_PARSE_STATE_H
#include <QByteArray>
#include <QStack>
namespace Debugger {
namespace Internal {
class NameDemanglerPrivate;
class ParseTreeNode;
class GlobalParseState
{
friend class NameDemanglerPrivate;
public:
char peek(int ahead = 0);
char advance(int steps = 1);
QByteArray readAhead(int charCount) const;
int stackElementCount() const { return m_parseStack.count(); }
ParseTreeNode *stackTop() const { return m_parseStack.top(); }
ParseTreeNode *stackElementAt(int index) const { return m_parseStack.at(index); }
void pushToStack(ParseTreeNode *node) { m_parseStack.push(node); }
ParseTreeNode *popFromStack() { return m_parseStack.pop(); }
int substitutionCount() const { return m_substitutions.count(); }
QByteArray substitutionAt(int index) const { return m_substitutions.at(index); }
void addSubstitution(const ParseTreeNode *node);
int templateParamCount() const { return m_templateParams.count(); }
ParseTreeNode *templateParamAt(int index) const { return m_templateParams.at(index); }
void addTemplateParam(ParseTreeNode *node) { m_templateParams << node; }
void clearTemplateParams() { m_templateParams.clear(); }
// TODO: Can we get rid of this by analyzing the stack?
bool isConversionOperator() const { return m_isConversionOperator; }
void setIsConversionOperator(bool is) { m_isConversionOperator = is; }
private:
int m_pos;
QByteArray m_mangledName;
QList<QByteArray> m_substitutions;
QList<ParseTreeNode *> m_templateParams;
bool m_isConversionOperator;
QStack<ParseTreeNode *> m_parseStack;
static const char eoi = '$';
};
} // namespace Internal
} // namespace Debugger
#endif // GLOBAL_PARSE_STATE_H
HEADERS += \
$$PWD/namedemangler.h \
$$PWD/parsetreenodes.h \
namedemangler/demanglerexceptions.h
$$PWD/demanglerexceptions.h \
$$PWD/globalparsestate.h
SOURCES += \
$$PWD/namedemangler.cpp \
$$PWD/parsetreenodes.cpp
$$PWD/parsetreenodes.cpp \
$$PWD/globalparsestate.cpp
......@@ -32,11 +32,15 @@
#ifndef PARSETREENODES_H
#define PARSETREENODES_H
#include "globalparsestate.h"
#include <QByteArray>
#include <QList>
#include <QSet>
#define CHILD_AT(obj, index) obj->childAt(index, Q_FUNC_INFO, __FILE__, __LINE__)
// TODO: Get the number of node objects in a tree down by only creating sub-nodes if there is really a need
// or things would get more complicated without them.
// Example for an unnecessary object: The parent type node of a function type node -- it holds zero information!
namespace Debugger {
namespace Internal {
......@@ -52,11 +56,25 @@ public:
ParseTreeNode *childAt(int i, const QString &func, const QString &file, int line) const;
QByteArray pasteAllChildren() const;
template <typename T> static T *parseRule(GlobalParseState *parseState)
{
T * const node = new T;
node->m_parseState = parseState;
parseState->pushToStack(node);
parseState->stackTop()->parse();
return node;
}
protected:
GlobalParseState *parseState() const { return m_parseState; }
void clearChildList() { m_children.clear(); }
private:
virtual void parse() = 0;
QList<ParseTreeNode *> m_children; // Convention: Children are inserted in parse order.
GlobalParseState *m_parseState;
};
class ArrayTypeNode : public ParseTreeNode
......@@ -65,6 +83,9 @@ public:
static bool mangledRepresentationStartsWith(char c);
QByteArray toByteArray() const;
private:
void parse();
};
class BareFunctionTypeNode : public ParseTreeNode
......@@ -72,8 +93,13 @@ class BareFunctionTypeNode : public ParseTreeNode
public:
static bool mangledRepresentationStartsWith(char c);
bool hasReturnType() const { return m_hasReturnType; }
QByteArray toByteArray() const;
private:
void parse();
bool m_hasReturnType;
};
......@@ -83,13 +109,19 @@ public:
static bool mangledRepresentationStartsWith(char c);
QByteArray toByteArray() const;
private:
void parse();
};
// TODO: DIE!!!
class PredefinedBuiltinTypeNode : public ParseTreeNode
{
public:
QByteArray toByteArray() const;
void parse() {}
enum Type {
VoidType, WCharType, BoolType,
PlainCharType, SignedCharType, UnsignedCharType, SignedShortType, UnsignedShortType,
......@@ -107,18 +139,27 @@ public:
static bool mangledRepresentationStartsWith(char c);
QByteArray toByteArray() const;
private:
void parse();
};
class NvOffsetNode : public ParseTreeNode
{
public:
QByteArray toByteArray() const { return QByteArray(); } // TODO: How to encode this?
private:
void parse();
};
class VOffsetNode : public ParseTreeNode
{
public:
QByteArray toByteArray() const { return QByteArray(); } // TODO: How to encode this?
private:
void parse();
};
class ClassEnumTypeNode : public ParseTreeNode
......@@ -127,6 +168,9 @@ public:
static bool mangledRepresentationStartsWith(char c);
QByteArray toByteArray() const;
private:
void parse();
};
class DiscriminatorNode : public ParseTreeNode
......@@ -135,6 +179,9 @@ public:
static bool mangledRepresentationStartsWith(char c);
QByteArray toByteArray() const;
private:
void parse();
};
class CtorDtorNameNode : public ParseTreeNode
......@@ -144,6 +191,9 @@ public:
QByteArray toByteArray() const;
private:
void parse();
bool m_isDestructor;
QByteArray m_representation;
};
......@@ -153,7 +203,11 @@ class CvQualifiersNode : public ParseTreeNode
public:
static bool mangledRepresentationStartsWith(char c);
bool hasQualifiers() const { return m_hasConst || m_hasVolatile; }
QByteArray toByteArray() const;
private:
void parse();
bool m_hasVolatile;
bool m_hasConst;
......@@ -165,6 +219,9 @@ public:
static bool mangledRepresentationStartsWith(char c);
QByteArray toByteArray() const;
private:
void parse();
};
class ExpressionNode : public ParseTreeNode
......@@ -174,6 +231,9 @@ public:
QByteArray toByteArray() const;
private:
void parse();
enum Type {
ConversionType, SizeofType, AlignofType, OperatorType, OtherType, ParameterPackSizeType
} m_type;
......@@ -184,8 +244,6 @@ 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,
......@@ -197,8 +255,15 @@ public:
LogicalAndType, LogicalOrType, IncrementType, DecrementType, CommaType, ArrowStarType,
ArrowType, CallType, IndexType, TernaryType, SizeofTypeType, SizeofExprType,
AlignofTypeType, AlignofExprType, CastType, VendorType
} m_type;
};
Type type() const { return m_type; }
QByteArray toByteArray() const;
private:
void parse();
Type m_type;
};
class ExprPrimaryNode : public ParseTreeNode
......@@ -207,6 +272,9 @@ public:
static bool mangledRepresentationStartsWith(char c);
QByteArray toByteArray() const;
private:
void parse();
};
class FunctionTypeNode : public ParseTreeNode
......@@ -214,8 +282,13 @@ class FunctionTypeNode : public ParseTreeNode
public:
static bool mangledRepresentationStartsWith(char c);
bool isExternC() const { return m_isExternC; }
QByteArray toByteArray() const;
private:
void parse();
bool m_isExternC;
};
......@@ -226,6 +299,9 @@ public:
QByteArray toByteArray() const;
private:
void parse();
bool m_isStringLiteral;
};
......@@ -235,15 +311,21 @@ public:
static bool mangledRepresentationStartsWith(char c);
QByteArray toByteArray() const;
private:
void parse();
};
class NumberNode : public ParseTreeNode
{
public:
static bool mangledRepresentationStartsWith(char c, int base = 10);
static bool mangledRepresentationStartsWith(char c);
QByteArray toByteArray() const;
private:
void parse();
bool m_isNegative;
};
......@@ -254,6 +336,9 @@ public:
QByteArray toByteArray() const { return m_name; }
private:
void parse();
QByteArray m_name;
};
......@@ -262,9 +347,12 @@ class UnqualifiedNameNode : public ParseTreeNode
public:
static bool mangledRepresentationStartsWith(char c);
bool isConstructorOrDestructorOrConversionOperator() const;
QByteArray toByteArray() const;
bool isConstructorOrDestructorOrConversionOperator() const;
private:
void parse();
};
class UnscopedNameNode : public ParseTreeNode
......@@ -272,9 +360,12 @@ class UnscopedNameNode : public ParseTreeNode
public:
static bool mangledRepresentationStartsWith(char c);
bool isConstructorOrDestructorOrConversionOperator() const;
QByteArray toByteArray() const;
bool isConstructorOrDestructorOrConversionOperator() const;
private:
void parse();
bool m_inStdNamespace;
};
......@@ -284,10 +375,13 @@ class NestedNameNode : public ParseTreeNode
public:
static bool mangledRepresentationStartsWith(char c);
QByteArray toByteArray() const;
bool isTemplate() const;
bool isConstructorOrDestructorOrConversionOperator() const;
QByteArray toByteArray() const;
private:
void parse();
};
class SubstitutionNode : public ParseTreeNode
......@@ -297,6 +391,9 @@ public:
QByteArray toByteArray() const;
private:
void parse();
enum Type {
ActualSubstitutionType, StdType, StdAllocType, StdBasicStringType, FullStdBasicStringType,
StdBasicIStreamType, StdBasicOStreamType, StdBasicIoStreamType
......@@ -310,6 +407,9 @@ public:
static bool mangledRepresentationStartsWith(char c);
QByteArray toByteArray() const;
private:
void parse();
};
class TemplateParamNode : public ParseTreeNode
......@@ -319,7 +419,14 @@ public:
static bool mangledRepresentationStartsWith(char c);
int index() const { return m_index; }
QByteArray toByteArray() const;
private:
void parse();
int m_index;
};
class TemplateArgsNode : public ParseTreeNode
......@@ -328,6 +435,9 @@ public:
static bool mangledRepresentationStartsWith(char c);
QByteArray toByteArray() const;
private:
void parse();
};
class SpecialNameNode : public ParseTreeNode
......@@ -337,19 +447,27 @@ public:
QByteArray toByteArray() const;
private:
void parse();
enum Type {
VirtualTableType, VttStructType, TypeInfoType, TypeInfoNameType, GuardVarType,
SingleCallOffsetType, DoubleCallOffsetType
} m_type;
};
class NonNegativeNumberNode : public ParseTreeNode
template<int base> class NonNegativeNumberNode : public ParseTreeNode
{
public:
static bool mangledRepresentationStartsWith(char c, int base = 10);
static bool mangledRepresentationStartsWith(char c);
quint64 number() const { return m_number; }
QByteArray toByteArray() const;
private:
void parse();
quint64 m_number;
};
......@@ -358,10 +476,13 @@ class NameNode : public ParseTreeNode
public:
static bool mangledRepresentationStartsWith(char c);
QByteArray toByteArray() const;
bool isTemplate() const;
bool isConstructorOrDestructorOrConversionOperator() const;
QByteArray toByteArray() const;
private:
void parse();
};
class TemplateArgNode : public ParseTreeNode
......@@ -371,6 +492,9 @@ public:
QByteArray toByteArray() const;
private:
void parse();
bool m_isTemplateArgumentPack;
};
......@@ -379,10 +503,13 @@ class Prefix2Node : public ParseTreeNode
public:
static bool mangledRepresentationStartsWith(char c);
QByteArray toByteArray() const;
bool isTemplate() const;
bool isConstructorOrDestructorOrConversionOperator() const;
QByteArray toByteArray() const;
private:
void parse();
};
class PrefixNode : public ParseTreeNode
......@@ -390,10 +517,13 @@ class PrefixNode : public ParseTreeNode
public:
static bool mangledRepresentationStartsWith(char c);
QByteArray toByteArray() const;
bool isTemplate() const;
bool isConstructorOrDestructorOrConversionOperator() const;
QByteArray toByteArray() const;
private:
void parse();
};