Name demangler: Fix reference collapsing.

Change-Id: I7bcf1ace346ffcb5e05242f6cedfc5439c97fff9
Reviewed-by: Christian Kandeler <christian.kandeler@nokia.com>
This commit is contained in:
Christian Kandeler
2012-08-10 16:46:38 +02:00
parent 2dc005cae7
commit 26c4329f74
7 changed files with 733 additions and 377 deletions

View File

@@ -31,6 +31,7 @@
#define DEMANGLEREXCEPTIONS_H #define DEMANGLEREXCEPTIONS_H
#include <QtGlobal> #include <QtGlobal>
#include <QSharedPointer>
#include <QString> #include <QString>
namespace Debugger { namespace Debugger {
@@ -64,10 +65,10 @@ public:
} \ } \
} while (0) } while (0)
template <typename T> T *demanglerCast(ParseTreeNode *node, const QString &func, template <typename T> QSharedPointer<T> demanglerCast(const QSharedPointer<ParseTreeNode> &node,
const QString &file, int line) const QString &func, const QString &file, int line)
{ {
T * const out = dynamic_cast<T *>(node); const QSharedPointer<T> out = node.dynamicCast<T>();
if (!out) if (!out)
throw InternalDemanglerException(func, file, line); throw InternalDemanglerException(func, file, line);
return out; return out;

View File

@@ -64,15 +64,9 @@ QByteArray GlobalParseState::readAhead(int charCount) const
return str; return str;
} }
void GlobalParseState::addSubstitution(const ParseTreeNode *node) void GlobalParseState::addSubstitution(const QSharedPointer<ParseTreeNode> &node)
{ {
addSubstitution(node->toByteArray()); m_substitutions << node->clone();
}
void GlobalParseState::addSubstitution(const QByteArray &symbol)
{
if (!symbol.isEmpty())
m_substitutions.append(symbol);
} }
} // namespace Internal } // namespace Internal

View File

@@ -31,6 +31,7 @@
#define GLOBAL_PARSE_STATE_H #define GLOBAL_PARSE_STATE_H
#include <QByteArray> #include <QByteArray>
#include <QSharedPointer>
#include <QStack> #include <QStack>
namespace Debugger { namespace Debugger {
@@ -47,25 +48,24 @@ public:
QByteArray readAhead(int charCount) const; QByteArray readAhead(int charCount) const;
int stackElementCount() const { return m_parseStack.count(); } int stackElementCount() const { return m_parseStack.count(); }
ParseTreeNode *stackTop() const { return m_parseStack.top(); } QSharedPointer<ParseTreeNode> stackTop() const { return m_parseStack.top(); }
ParseTreeNode *stackElementAt(int index) const { return m_parseStack.at(index); } QSharedPointer<ParseTreeNode> stackElementAt(int index) const { return m_parseStack.at(index); }
void pushToStack(ParseTreeNode *node) { m_parseStack.push(node); } void pushToStack(const QSharedPointer<ParseTreeNode> &node) { m_parseStack.push(node); }
ParseTreeNode *popFromStack() { return m_parseStack.pop(); } QSharedPointer<ParseTreeNode> popFromStack() { return m_parseStack.pop(); }
int substitutionCount() const { return m_substitutions.count(); } int substitutionCount() const { return m_substitutions.count(); }
QByteArray substitutionAt(int index) const { return m_substitutions.at(index); } QSharedPointer<ParseTreeNode> substitutionAt(int index) const { return m_substitutions.at(index); }
void addSubstitution(const ParseTreeNode *node); void addSubstitution(const QSharedPointer<ParseTreeNode> &node);
void addSubstitution(const QByteArray &symbol);
int templateParamCount() const { return m_templateParams.count(); } int templateParamCount() const { return m_templateParams.count(); }
ParseTreeNode *templateParamAt(int index) const { return m_templateParams.at(index); } QSharedPointer<ParseTreeNode> templateParamAt(int index) const { return m_templateParams.at(index); }
void addTemplateParam(ParseTreeNode *node) { m_templateParams << node; } void addTemplateParam(const QSharedPointer<ParseTreeNode> &node) { m_templateParams << node; }
private: private:
int m_pos; int m_pos;
QByteArray m_mangledName; QByteArray m_mangledName;
QList<QByteArray> m_substitutions; QList<QSharedPointer<ParseTreeNode> > m_substitutions;
QList<ParseTreeNode *> m_templateParams; QList<QSharedPointer<ParseTreeNode> > m_templateParams;
QStack<ParseTreeNode *> m_parseStack; QStack<QSharedPointer<ParseTreeNode> > m_parseStack;
static const char eoi = '$'; static const char eoi = '$';
}; };

View File

@@ -65,29 +65,18 @@ bool NameDemanglerPrivate::demangle(const QString &mangledName)
return true; return true;
} }
MangledNameRule::parse(&m_parseState, 0); MangledNameRule::parse(&m_parseState, ParseTreeNode::Ptr());
if (m_parseState.m_pos != m_parseState.m_mangledName.size()) if (m_parseState.m_pos != m_parseState.m_mangledName.size())
throw ParseException(QLatin1String("Unconsumed input")); throw ParseException(QLatin1String("Unconsumed input"));
if (m_parseState.m_parseStack.count() != 1) { if (m_parseState.m_parseStack.count() != 1) {
throw ParseException(QString::fromLocal8Bit("There are %1 elements on the parse stack; " throw ParseException(QString::fromLocal8Bit("There are %1 elements on the parse stack; "
"expected one.").arg(m_parseState.m_parseStack.count())); "expected one.").arg(m_parseState.m_parseStack.count()));
} }
m_demangledName = m_parseState.m_parseStack.top()->toByteArray();
/* // Uncomment for debugging.
* FIXME: This is a hack we do because TypeNode::toByteArray() cannot catch all //m_parseState.stackTop()->print(0);
* all nested reference due to the way substitutions are currently implented.
* Note that even with this hack, we do not catch things like
* "reference to reference to array", because the operators do not follow each other
* in the string.
* For a correct solution, we'll probably have to clone substitution nodes instead of
* just dumping their strings (which means adding a copy constructor and a clone function
* to every node).
*/
m_demangledName.replace("&& &&", "&&");
m_demangledName.replace("&& &", "&");
m_demangledName.replace(" & &", "&");
m_demangledName = m_parseState.stackTop()->toByteArray();
success = true; success = true;
} catch (const ParseException &p) { } catch (const ParseException &p) {
m_errorString = QString::fromLocal8Bit("Parse error at index %1 of mangled name '%2': %3.") m_errorString = QString::fromLocal8Bit("Parse error at index %1 of mangled name '%2': %3.")
@@ -99,7 +88,6 @@ bool NameDemanglerPrivate::demangle(const QString &mangledName)
success = false; success = false;
} }
qDeleteAll(m_parseState.m_parseStack);
m_parseState.m_parseStack.clear(); m_parseState.m_parseStack.clear();
m_parseState.m_substitutions.clear(); m_parseState.m_substitutions.clear();
m_parseState.m_templateParams.clear(); m_parseState.m_templateParams.clear();

File diff suppressed because it is too large Load Diff

View File

@@ -35,6 +35,7 @@
#include <QByteArray> #include <QByteArray>
#include <QList> #include <QList>
#include <QSet> #include <QSet>
#include <QSharedPointer>
namespace Debugger { namespace Debugger {
namespace Internal { namespace Internal {
@@ -42,57 +43,73 @@ namespace Internal {
class ParseTreeNode class ParseTreeNode
{ {
public: public:
typedef QSharedPointer<ParseTreeNode> Ptr;
virtual ~ParseTreeNode(); virtual ~ParseTreeNode();
virtual QByteArray toByteArray() const = 0; virtual QByteArray toByteArray() const = 0;
virtual ParseTreeNode::Ptr clone() const = 0;
int childCount() const { return m_children.count(); } int childCount() const { return m_children.count(); }
void addChild(ParseTreeNode *childNode) { m_children << childNode; } void addChild(ParseTreeNode::Ptr childNode) { m_children << childNode; }
ParseTreeNode *childAt(int i, const QString &func, const QString &file, int line) const; ParseTreeNode::Ptr childAt(int i, const QString &func, const QString &file, int line) const;
QByteArray pasteAllChildren() const; QByteArray pasteAllChildren() const;
template <typename T> static T *parseRule(GlobalParseState *parseState) void print(int indentation) const; // For debugging.
template <typename T> static Ptr parseRule(GlobalParseState *parseState)
{ {
T * const node = new T; const Ptr node = Ptr(new T(parseState));
node->m_parseState = parseState;
parseState->pushToStack(node); parseState->pushToStack(node);
parseState->stackTop()->parse(); parseState->stackTop()->parse();
return node; return node;
} }
protected: protected:
GlobalParseState *parseState() const { return m_parseState; } ParseTreeNode(GlobalParseState *parseState) : m_parseState(parseState) {}
ParseTreeNode(const ParseTreeNode &other);
QByteArray bool2String(bool b) const;
void clearChildList() { m_children.clear(); } GlobalParseState *parseState() const { return m_parseState; }
private: private:
virtual void parse() = 0; virtual void parse() = 0;
virtual QByteArray description() const = 0; // For debugging.
QList<ParseTreeNode *> m_children; // Convention: Children are inserted in parse order. QList<ParseTreeNode::Ptr > m_children; // Convention: Children are inserted in parse order.
GlobalParseState *m_parseState; GlobalParseState * const m_parseState;
}; };
class ArrayTypeNode : public ParseTreeNode class ArrayTypeNode : public ParseTreeNode
{ {
public: public:
ArrayTypeNode(GlobalParseState *parseState) : ParseTreeNode(parseState) {}
static bool mangledRepresentationStartsWith(char c); static bool mangledRepresentationStartsWith(char c);
QByteArray toByteArray() const; QByteArray toByteArray() const;
private: private:
ArrayTypeNode(const ArrayTypeNode &other) : ParseTreeNode(other) {}
ParseTreeNode::Ptr clone() const { return Ptr(new ArrayTypeNode(*this)); }
void parse(); void parse();
QByteArray description() const { return "ArrayType"; }
}; };
class BareFunctionTypeNode : public ParseTreeNode class BareFunctionTypeNode : public ParseTreeNode
{ {
public: public:
typedef QSharedPointer<BareFunctionTypeNode> Ptr;
BareFunctionTypeNode(GlobalParseState *parseState);
static bool mangledRepresentationStartsWith(char c); static bool mangledRepresentationStartsWith(char c);
bool hasReturnType() const { return m_hasReturnType; } bool hasReturnType() const { return m_hasReturnType; }
QByteArray toByteArray() const; QByteArray toByteArray() const;
private: private:
BareFunctionTypeNode(const BareFunctionTypeNode &other);
ParseTreeNode::Ptr clone() const { return Ptr(new BareFunctionTypeNode(*this)); }
void parse(); void parse();
QByteArray description() const;
bool m_hasReturnType; bool m_hasReturnType;
}; };
@@ -100,8 +117,9 @@ private:
class BuiltinTypeNode : public ParseTreeNode class BuiltinTypeNode : public ParseTreeNode
{ {
public: public:
typedef QSharedPointer<BuiltinTypeNode> Ptr;
BuiltinTypeNode(GlobalParseState *parseState) : ParseTreeNode(parseState) {}
static bool mangledRepresentationStartsWith(char c); static bool mangledRepresentationStartsWith(char c);
QByteArray toByteArray() const; QByteArray toByteArray() const;
enum Type { enum Type {
@@ -116,7 +134,10 @@ public:
Type type() const { return m_type; } Type type() const { return m_type; }
private: private:
BuiltinTypeNode(const BuiltinTypeNode &other);
ParseTreeNode::Ptr clone() const { return Ptr(new BuiltinTypeNode(*this)); }
void parse(); void parse();
QByteArray description() const;
Type m_type; Type m_type;
}; };
@@ -125,7 +146,7 @@ class CallOffsetRule
{ {
public: public:
static bool mangledRepresentationStartsWith(char c); static bool mangledRepresentationStartsWith(char c);
static void parse(GlobalParseState *parseState, ParseTreeNode *parentNode); static void parse(GlobalParseState *parseState);
private: private:
CallOffsetRule(); CallOffsetRule();
@@ -134,26 +155,34 @@ private:
class NvOffsetNode : public ParseTreeNode class NvOffsetNode : public ParseTreeNode
{ {
public: public:
NvOffsetNode(GlobalParseState *parseState) : ParseTreeNode(parseState) {}
QByteArray toByteArray() const { return QByteArray(); } // TODO: How to encode this? QByteArray toByteArray() const { return QByteArray(); } // TODO: How to encode this?
private: private:
NvOffsetNode(const NvOffsetNode &other) : ParseTreeNode(other) {}
ParseTreeNode::Ptr clone() const { return Ptr(new NvOffsetNode(*this)); }
void parse(); void parse();
QByteArray description() const { return "NvOffset"; }
}; };
class VOffsetNode : public ParseTreeNode class VOffsetNode : public ParseTreeNode
{ {
public: public:
VOffsetNode(GlobalParseState *parseState) : ParseTreeNode(parseState) {}
QByteArray toByteArray() const { return QByteArray(); } // TODO: How to encode this? QByteArray toByteArray() const { return QByteArray(); } // TODO: How to encode this?
private: private:
VOffsetNode(const VOffsetNode &other) : ParseTreeNode(other) {}
ParseTreeNode::Ptr clone() const { return Ptr(new VOffsetNode(*this)); }
void parse(); void parse();
QByteArray description() const { return "VOffset"; }
}; };
class ClassEnumTypeRule class ClassEnumTypeRule
{ {
public: public:
static bool mangledRepresentationStartsWith(char c); static bool mangledRepresentationStartsWith(char c);
static void parse(GlobalParseState *parseState, ParseTreeNode *parentNode); static void parse(GlobalParseState *parseState);
private: private:
ClassEnumTypeRule(); ClassEnumTypeRule();
@@ -163,7 +192,7 @@ class DiscriminatorRule
{ {
public: public:
static bool mangledRepresentationStartsWith(char c); static bool mangledRepresentationStartsWith(char c);
static void parse(GlobalParseState *parseState, ParseTreeNode *parentNode); static void parse(GlobalParseState *parseState);
private: private:
DiscriminatorRule(); DiscriminatorRule();
@@ -172,12 +201,15 @@ private:
class CtorDtorNameNode : public ParseTreeNode class CtorDtorNameNode : public ParseTreeNode
{ {
public: public:
CtorDtorNameNode(GlobalParseState *parseState) : ParseTreeNode(parseState) {}
static bool mangledRepresentationStartsWith(char c); static bool mangledRepresentationStartsWith(char c);
QByteArray toByteArray() const; QByteArray toByteArray() const;
private: private:
CtorDtorNameNode(const CtorDtorNameNode &other);
ParseTreeNode::Ptr clone() const { return Ptr(new CtorDtorNameNode(*this)); }
void parse(); void parse();
QByteArray description() const;
bool m_isDestructor; bool m_isDestructor;
QByteArray m_representation; QByteArray m_representation;
@@ -186,38 +218,47 @@ private:
class CvQualifiersNode : public ParseTreeNode class CvQualifiersNode : public ParseTreeNode
{ {
public: public:
typedef QSharedPointer<CvQualifiersNode> Ptr;
CvQualifiersNode(GlobalParseState *parseState);
static bool mangledRepresentationStartsWith(char c); static bool mangledRepresentationStartsWith(char c);
bool hasQualifiers() const { return m_hasConst || m_hasVolatile; } bool hasQualifiers() const { return m_hasConst || m_hasVolatile; }
QByteArray toByteArray() const; QByteArray toByteArray() const;
private: private:
CvQualifiersNode(const CvQualifiersNode &other);
ParseTreeNode::Ptr clone() const { return Ptr(new CvQualifiersNode(*this)); }
void parse(); void parse();
QByteArray description() const { return "CvQualifiers[" + toByteArray() + ']'; }
bool m_hasVolatile;
bool m_hasConst; bool m_hasConst;
bool m_hasVolatile;
}; };
class EncodingNode : public ParseTreeNode class EncodingNode : public ParseTreeNode
{ {
public: public:
EncodingNode(GlobalParseState *parseState) : ParseTreeNode(parseState) {}
static bool mangledRepresentationStartsWith(char c); static bool mangledRepresentationStartsWith(char c);
QByteArray toByteArray() const; QByteArray toByteArray() const;
private: private:
EncodingNode(const EncodingNode &other) : ParseTreeNode(other) {}
ParseTreeNode::Ptr clone() const { return Ptr(new EncodingNode(*this)); }
void parse(); void parse();
QByteArray description() const { return "Encoding"; }
}; };
class ExpressionNode : public ParseTreeNode class ExpressionNode : public ParseTreeNode
{ {
public: public:
ExpressionNode(GlobalParseState *parseState);
static bool mangledRepresentationStartsWith(char c); static bool mangledRepresentationStartsWith(char c);
QByteArray toByteArray() const; QByteArray toByteArray() const;
private: private:
ExpressionNode(const ExpressionNode &other);
ParseTreeNode::Ptr clone() const { return Ptr(new ExpressionNode(*this)); }
void parse(); void parse();
QByteArray description() const;
enum Type { enum Type {
ConversionType, SizeofType, AlignofType, OperatorType, ParameterPackSizeType, ConversionType, SizeofType, AlignofType, OperatorType, ParameterPackSizeType,
@@ -233,6 +274,8 @@ private:
class OperatorNameNode : public ParseTreeNode class OperatorNameNode : public ParseTreeNode
{ {
public: public:
typedef QSharedPointer<OperatorNameNode> Ptr;
OperatorNameNode(GlobalParseState *parseState) : ParseTreeNode(parseState) {}
static bool mangledRepresentationStartsWith(char c); static bool mangledRepresentationStartsWith(char c);
enum Type { enum Type {
@@ -252,7 +295,10 @@ public:
QByteArray toByteArray() const; QByteArray toByteArray() const;
private: private:
OperatorNameNode(const OperatorNameNode &other);
ParseTreeNode::Ptr clone() const { return Ptr(new OperatorNameNode(*this)); }
void parse(); void parse();
QByteArray description() const;
Type m_type; Type m_type;
}; };
@@ -260,12 +306,16 @@ private:
class ExprPrimaryNode : public ParseTreeNode class ExprPrimaryNode : public ParseTreeNode
{ {
public: public:
ExprPrimaryNode(GlobalParseState *parseState);
static bool mangledRepresentationStartsWith(char c); static bool mangledRepresentationStartsWith(char c);
QByteArray toByteArray() const; QByteArray toByteArray() const;
private: private:
ExprPrimaryNode(const ExprPrimaryNode &other);
ParseTreeNode::Ptr clone() const { return Ptr(new ExprPrimaryNode(*this)); }
void parse(); void parse();
QByteArray description() const;
QByteArray m_suffix; QByteArray m_suffix;
bool m_isNullPtr; bool m_isNullPtr;
@@ -274,14 +324,17 @@ private:
class FunctionTypeNode : public ParseTreeNode class FunctionTypeNode : public ParseTreeNode
{ {
public: public:
typedef QSharedPointer<FunctionTypeNode> Ptr;
FunctionTypeNode(GlobalParseState *parseState);
static bool mangledRepresentationStartsWith(char c); static bool mangledRepresentationStartsWith(char c);
bool isExternC() const { return m_isExternC; } bool isExternC() const { return m_isExternC; }
QByteArray toByteArray() const; QByteArray toByteArray() const;
private: private:
FunctionTypeNode(const FunctionTypeNode &other);
ParseTreeNode::Ptr clone() const { return Ptr(new FunctionTypeNode(*this)); }
void parse(); void parse();
QByteArray description() const;
bool m_isExternC; bool m_isExternC;
}; };
@@ -289,16 +342,19 @@ private:
class LocalNameNode : public ParseTreeNode class LocalNameNode : public ParseTreeNode
{ {
public: public:
typedef QSharedPointer<LocalNameNode> Ptr;
LocalNameNode(GlobalParseState *parseState);
static bool mangledRepresentationStartsWith(char c); static bool mangledRepresentationStartsWith(char c);
QByteArray toByteArray() const; QByteArray toByteArray() const;
bool isTemplate() const; bool isTemplate() const;
bool isConstructorOrDestructorOrConversionOperator() const; bool isConstructorOrDestructorOrConversionOperator() const;
const CvQualifiersNode *cvQualifiers() const; CvQualifiersNode::Ptr cvQualifiers() const;
private: private:
LocalNameNode(const LocalNameNode &other);
ParseTreeNode::Ptr clone() const { return Ptr(new LocalNameNode(*this)); }
void parse(); void parse();
QByteArray description() const;
bool m_isStringLiteral; bool m_isStringLiteral;
bool m_isDefaultArg; bool m_isDefaultArg;
@@ -308,7 +364,7 @@ class MangledNameRule
{ {
public: public:
static bool mangledRepresentationStartsWith(char c); static bool mangledRepresentationStartsWith(char c);
static void parse(GlobalParseState *parseState, ParseTreeNode *parentNode); static void parse(GlobalParseState *parseState, const ParseTreeNode::Ptr &parentNode);
private: private:
MangledNameRule(); MangledNameRule();
@@ -317,12 +373,15 @@ private:
class NumberNode : public ParseTreeNode class NumberNode : public ParseTreeNode
{ {
public: public:
NumberNode(GlobalParseState *parseState);
static bool mangledRepresentationStartsWith(char c); static bool mangledRepresentationStartsWith(char c);
QByteArray toByteArray() const; QByteArray toByteArray() const;
private: private:
NumberNode(const NumberNode &other);
ParseTreeNode::Ptr clone() const { return Ptr(new NumberNode(*this)); }
void parse(); void parse();
QByteArray description() const;
bool m_isNegative; bool m_isNegative;
}; };
@@ -330,12 +389,15 @@ private:
class SourceNameNode : public ParseTreeNode class SourceNameNode : public ParseTreeNode
{ {
public: public:
SourceNameNode(GlobalParseState *parseState) : ParseTreeNode(parseState) {}
static bool mangledRepresentationStartsWith(char c); static bool mangledRepresentationStartsWith(char c);
QByteArray toByteArray() const { return m_name; } QByteArray toByteArray() const { return m_name; }
private: private:
SourceNameNode(const SourceNameNode &other);
ParseTreeNode::Ptr clone() const { return Ptr(new SourceNameNode(*this)); }
void parse(); void parse();
QByteArray description() const;
QByteArray m_name; QByteArray m_name;
}; };
@@ -343,27 +405,32 @@ private:
class UnqualifiedNameNode : public ParseTreeNode class UnqualifiedNameNode : public ParseTreeNode
{ {
public: public:
typedef QSharedPointer<UnqualifiedNameNode> Ptr;
UnqualifiedNameNode(GlobalParseState *parseState) : ParseTreeNode(parseState) {}
static bool mangledRepresentationStartsWith(char c); static bool mangledRepresentationStartsWith(char c);
bool isConstructorOrDestructorOrConversionOperator() const; bool isConstructorOrDestructorOrConversionOperator() const;
QByteArray toByteArray() const; QByteArray toByteArray() const;
private: private:
UnqualifiedNameNode(const UnqualifiedNameNode &other) : ParseTreeNode(other) {}
ParseTreeNode::Ptr clone() const { return Ptr(new UnqualifiedNameNode(*this)); }
void parse(); void parse();
QByteArray description() const { return "UnqualifiedName"; }
}; };
class UnscopedNameNode : public ParseTreeNode class UnscopedNameNode : public ParseTreeNode
{ {
public: public:
UnscopedNameNode(GlobalParseState *parseState);
static bool mangledRepresentationStartsWith(char c); static bool mangledRepresentationStartsWith(char c);
bool isConstructorOrDestructorOrConversionOperator() const; bool isConstructorOrDestructorOrConversionOperator() const;
QByteArray toByteArray() const; QByteArray toByteArray() const;
private: private:
UnscopedNameNode(const UnscopedNameNode &other);
ParseTreeNode::Ptr clone() const { return Ptr(new UnscopedNameNode(*this)); }
void parse(); void parse();
QByteArray description() const;
bool m_inStdNamespace; bool m_inStdNamespace;
}; };
@@ -371,50 +438,67 @@ private:
class NestedNameNode : public ParseTreeNode class NestedNameNode : public ParseTreeNode
{ {
public: public:
typedef QSharedPointer<NestedNameNode> Ptr;
NestedNameNode(GlobalParseState *parseState) : ParseTreeNode(parseState ){}
static bool mangledRepresentationStartsWith(char c); static bool mangledRepresentationStartsWith(char c);
bool isTemplate() const; bool isTemplate() const;
bool isConstructorOrDestructorOrConversionOperator() const; bool isConstructorOrDestructorOrConversionOperator() const;
const CvQualifiersNode *cvQualifiers() const; CvQualifiersNode::Ptr cvQualifiers() const;
QByteArray toByteArray() const; QByteArray toByteArray() const;
private: private:
NestedNameNode(const NestedNameNode &other) : ParseTreeNode(other) {}
ParseTreeNode::Ptr clone() const { return Ptr(new NestedNameNode(*this)); }
void parse(); void parse();
QByteArray description() const { return "NestedName"; }
}; };
class SubstitutionNode : public ParseTreeNode class SubstitutionNode : public ParseTreeNode
{ {
public: public:
typedef QSharedPointer<SubstitutionNode> Ptr;
SubstitutionNode(GlobalParseState *parseState) : ParseTreeNode(parseState) {}
static bool mangledRepresentationStartsWith(char c); static bool mangledRepresentationStartsWith(char c);
QByteArray toByteArray() const; QByteArray toByteArray() const;
private:
void parse();
enum Type { enum Type {
ActualSubstitutionType, StdType, StdAllocType, StdBasicStringType, FullStdBasicStringType, ActualSubstitutionType, StdType, StdAllocType, StdBasicStringType, FullStdBasicStringType,
StdBasicIStreamType, StdBasicOStreamType, StdBasicIoStreamType StdBasicIStreamType, StdBasicOStreamType, StdBasicIoStreamType
} m_type; };
QByteArray m_substValue; Type type() const { return m_type; }
private:
SubstitutionNode(const SubstitutionNode &other);
ParseTreeNode::Ptr clone() const { return Ptr(new SubstitutionNode(*this)); }
void parse();
QByteArray description() const;
Type m_type;
}; };
class PointerToMemberTypeNode : public ParseTreeNode class PointerToMemberTypeNode : public ParseTreeNode
{ {
public: public:
PointerToMemberTypeNode(GlobalParseState *parseState) : ParseTreeNode(parseState) {}
static bool mangledRepresentationStartsWith(char c); static bool mangledRepresentationStartsWith(char c);
QByteArray toByteArray() const; QByteArray toByteArray() const;
private: private:
PointerToMemberTypeNode(const PointerToMemberTypeNode &other) : ParseTreeNode(other) {}
ParseTreeNode::Ptr clone() const { return Ptr(new PointerToMemberTypeNode(*this)); }
void parse(); void parse();
QByteArray description() const { return "PointerToMember"; }
}; };
class TemplateParamNode : public ParseTreeNode class TemplateParamNode : public ParseTreeNode
{ {
public: public:
~TemplateParamNode(); typedef QSharedPointer<TemplateParamNode> Ptr;
TemplateParamNode(GlobalParseState *parseState) : ParseTreeNode(parseState) {}
static bool mangledRepresentationStartsWith(char c); static bool mangledRepresentationStartsWith(char c);
@@ -423,7 +507,10 @@ public:
QByteArray toByteArray() const; QByteArray toByteArray() const;
private: private:
TemplateParamNode(const TemplateParamNode &other);
ParseTreeNode::Ptr clone() const { return Ptr(new TemplateParamNode(*this)); }
void parse(); void parse();
QByteArray description() const;
int m_index; int m_index;
}; };
@@ -431,23 +518,29 @@ private:
class TemplateArgsNode : public ParseTreeNode class TemplateArgsNode : public ParseTreeNode
{ {
public: public:
TemplateArgsNode(GlobalParseState *parseState) : ParseTreeNode(parseState) {}
static bool mangledRepresentationStartsWith(char c); static bool mangledRepresentationStartsWith(char c);
QByteArray toByteArray() const; QByteArray toByteArray() const;
private: private:
TemplateArgsNode(const TemplateArgsNode &other) : ParseTreeNode(other) {}
ParseTreeNode::Ptr clone() const { return Ptr(new TemplateArgsNode(*this)); }
void parse(); void parse();
QByteArray description() const { return "TemplateArgs"; }
}; };
class SpecialNameNode : public ParseTreeNode class SpecialNameNode : public ParseTreeNode
{ {
public: public:
SpecialNameNode(GlobalParseState *parseState) : ParseTreeNode(parseState) {}
static bool mangledRepresentationStartsWith(char c); static bool mangledRepresentationStartsWith(char c);
QByteArray toByteArray() const; QByteArray toByteArray() const;
private: private:
SpecialNameNode(const SpecialNameNode &other);
ParseTreeNode::Ptr clone() const { return Ptr(new SpecialNameNode(*this)); }
void parse(); void parse();
QByteArray description() const;
enum Type { enum Type {
VirtualTableType, VttStructType, TypeInfoType, TypeInfoNameType, GuardVarType, VirtualTableType, VttStructType, TypeInfoType, TypeInfoNameType, GuardVarType,
@@ -458,14 +551,17 @@ private:
template<int base> class NonNegativeNumberNode : public ParseTreeNode template<int base> class NonNegativeNumberNode : public ParseTreeNode
{ {
public: public:
typedef QSharedPointer<NonNegativeNumberNode<base> > Ptr;
NonNegativeNumberNode(GlobalParseState *parseState) : ParseTreeNode(parseState) {}
static bool mangledRepresentationStartsWith(char c); static bool mangledRepresentationStartsWith(char c);
quint64 number() const { return m_number; } quint64 number() const { return m_number; }
QByteArray toByteArray() const; QByteArray toByteArray() const;
private: private:
NonNegativeNumberNode(const NonNegativeNumberNode &other);
ParseTreeNode::Ptr clone() const { return Ptr(new NonNegativeNumberNode<base>(*this)); }
void parse(); void parse();
QByteArray description() const;
quint64 m_number; quint64 m_number;
}; };
@@ -473,48 +569,47 @@ private:
class NameNode : public ParseTreeNode class NameNode : public ParseTreeNode
{ {
public: public:
typedef QSharedPointer<NameNode> Ptr;
NameNode(GlobalParseState *parseState) : ParseTreeNode(parseState) {}
static bool mangledRepresentationStartsWith(char c); static bool mangledRepresentationStartsWith(char c);
bool isTemplate() const; bool isTemplate() const;
bool isConstructorOrDestructorOrConversionOperator() const; bool isConstructorOrDestructorOrConversionOperator() const;
const CvQualifiersNode *cvQualifiers() const; CvQualifiersNode::Ptr cvQualifiers() const;
QByteArray toByteArray() const; QByteArray toByteArray() const;
private: private:
NameNode(const NameNode &other) : ParseTreeNode(other) {}
ParseTreeNode::Ptr clone() const { return Ptr(new NameNode(*this)); }
void parse(); void parse();
QByteArray description() const { return "Name"; }
}; };
class TemplateArgNode : public ParseTreeNode class TemplateArgNode : public ParseTreeNode
{ {
public: public:
TemplateArgNode(GlobalParseState *parseState);
static bool mangledRepresentationStartsWith(char c); static bool mangledRepresentationStartsWith(char c);
QByteArray toByteArray() const; QByteArray toByteArray() const;
private: private:
TemplateArgNode(const TemplateArgNode &other);
ParseTreeNode::Ptr clone() const { return Ptr(new TemplateArgNode(*this)); }
void parse(); void parse();
QByteArray description() const;
bool m_isTemplateArgumentPack; bool m_isTemplateArgumentPack;
}; };
class Prefix2Node : public ParseTreeNode
{
public:
static bool mangledRepresentationStartsWith(char c);
bool isTemplate() const;
bool isConstructorOrDestructorOrConversionOperator() const;
QByteArray toByteArray() const;
private:
void parse();
};
class PrefixNode : public ParseTreeNode class PrefixNode : public ParseTreeNode
{ {
public: public:
typedef QSharedPointer<PrefixNode> Ptr;
PrefixNode(GlobalParseState *parseState) : ParseTreeNode(parseState) {}
static bool mangledRepresentationStartsWith(char c); static bool mangledRepresentationStartsWith(char c);
bool isTemplate() const; bool isTemplate() const;
@@ -523,24 +618,34 @@ public:
QByteArray toByteArray() const; QByteArray toByteArray() const;
private: private:
PrefixNode(const PrefixNode &other) : ParseTreeNode(other) {}
ParseTreeNode::Ptr clone() const { return Ptr(new PrefixNode(*this)); }
void parse(); void parse();
QByteArray description() const { return "Prefix"; }
}; };
class TypeNode : public ParseTreeNode class TypeNode : public ParseTreeNode
{ {
public: public:
typedef QSharedPointer<TypeNode> Ptr;
TypeNode(GlobalParseState *parseState) : ParseTreeNode(parseState), m_type(OtherType) {}
static bool mangledRepresentationStartsWith(char c); static bool mangledRepresentationStartsWith(char c);
enum Type { enum Type {
QualifiedType, PointerType, ReferenceType, RValueType, VendorType, PackExpansionType, QualifiedType, PointerType, ReferenceType, RValueType, VendorType, PackExpansionType,
OtherType SubstitutionType, OtherType
}; };
Type type() const { return m_type; } Type type() const { return m_type; }
QByteArray toByteArray() const; QByteArray toByteArray() const;
private: private:
TypeNode(const TypeNode &other);
ParseTreeNode::Ptr clone() const { return Ptr(new TypeNode(*this)); }
void parse(); void parse();
QByteArray description() const;
QByteArray toByteArrayQualPointerRef(const TypeNode *typeNode, QByteArray toByteArrayQualPointerRef(const TypeNode *typeNode,
const QByteArray &qualPtrRef) const; const QByteArray &qualPtrRef) const;
@@ -552,61 +657,79 @@ private:
class FloatValueNode : public ParseTreeNode class FloatValueNode : public ParseTreeNode
{ {
public: public:
FloatValueNode(GlobalParseState *parseState) : ParseTreeNode(parseState) {}
static bool mangledRepresentationStartsWith(char c); static bool mangledRepresentationStartsWith(char c);
QByteArray toByteArray() const; QByteArray toByteArray() const;
private: private:
FloatValueNode(const FloatValueNode &other);
ParseTreeNode::Ptr clone() const { return Ptr(new FloatValueNode(*this)); }
void parse(); void parse();
QByteArray description() const;
double m_value; double m_value;
}; };
class LambdaSigNode : public ParseTreeNode class LambdaSigNode : public ParseTreeNode
{ {
public:
LambdaSigNode(GlobalParseState *parseState) : ParseTreeNode(parseState) {}
static bool mangledRepresentationStartsWith(char c); static bool mangledRepresentationStartsWith(char c);
QByteArray toByteArray() const; QByteArray toByteArray() const;
private: private:
LambdaSigNode(const LambdaSigNode &other) : ParseTreeNode(other) {}
ParseTreeNode::Ptr clone() const { return Ptr(new LambdaSigNode(*this)); }
void parse(); void parse();
QByteArray description() const { return "LambdaSig"; }
}; };
class ClosureTypeNameNode : public ParseTreeNode class ClosureTypeNameNode : public ParseTreeNode
{ {
public:
ClosureTypeNameNode(GlobalParseState *parseState) : ParseTreeNode(parseState) {}
QByteArray toByteArray() const; QByteArray toByteArray() const;
private: private:
ClosureTypeNameNode(const ClosureTypeNameNode &other) : ParseTreeNode(other) {}
ParseTreeNode::Ptr clone() const { return Ptr(new ClosureTypeNameNode(*this)); }
void parse(); void parse();
QByteArray description() const { return "ClosureType"; }
}; };
class UnnamedTypeNameNode : public ParseTreeNode class UnnamedTypeNameNode : public ParseTreeNode
{ {
public: public:
UnnamedTypeNameNode(GlobalParseState *parseState) : ParseTreeNode(parseState) {}
static bool mangledRepresentationStartsWith(char c); static bool mangledRepresentationStartsWith(char c);
QByteArray toByteArray() const; QByteArray toByteArray() const;
private: private:
UnnamedTypeNameNode(const UnnamedTypeNameNode &other) : ParseTreeNode(other) {}
ParseTreeNode::Ptr clone() const { return Ptr(new UnnamedTypeNameNode(*this)); }
void parse(); void parse();
QByteArray description() const { return "UnnnamedType"; }
}; };
class DeclTypeNode : public ParseTreeNode class DeclTypeNode : public ParseTreeNode
{ {
public: public:
DeclTypeNode(GlobalParseState *parseState) : ParseTreeNode(parseState) {}
static bool mangledRepresentationStartsWith(char c); static bool mangledRepresentationStartsWith(char c);
QByteArray toByteArray() const; QByteArray toByteArray() const;
private: private:
DeclTypeNode(const DeclTypeNode &other) : ParseTreeNode(other) {}
ParseTreeNode::Ptr clone() const { return Ptr(new DeclTypeNode(*this)); }
void parse(); void parse();
QByteArray description() const { return "DeclType"; }
}; };
class UnresolvedTypeRule class UnresolvedTypeRule
{ {
public: public:
static bool mangledRepresentationStartsWith(char c); static bool mangledRepresentationStartsWith(char c);
static void parse(GlobalParseState *parseState, ParseTreeNode *parentNode); static void parse(GlobalParseState *parseState);
private: private:
UnresolvedTypeRule(); UnresolvedTypeRule();
@@ -615,29 +738,36 @@ private:
class SimpleIdNode : public ParseTreeNode class SimpleIdNode : public ParseTreeNode
{ {
public: public:
SimpleIdNode(GlobalParseState *parseState) : ParseTreeNode(parseState) {}
static bool mangledRepresentationStartsWith(char c); static bool mangledRepresentationStartsWith(char c);
QByteArray toByteArray() const; QByteArray toByteArray() const;
private: private:
SimpleIdNode(const SimpleIdNode &other) : ParseTreeNode(other) {}
ParseTreeNode::Ptr clone() const { return Ptr(new SimpleIdNode(*this)); }
void parse(); void parse();
QByteArray description() const { return "SimpleId"; }
}; };
class DestructorNameNode : public ParseTreeNode class DestructorNameNode : public ParseTreeNode
{ {
public:
DestructorNameNode(GlobalParseState *parseState) : ParseTreeNode(parseState) {}
static bool mangledRepresentationStartsWith(char c); static bool mangledRepresentationStartsWith(char c);
QByteArray toByteArray() const; QByteArray toByteArray() const;
private: private:
DestructorNameNode(const DestructorNameNode &other) : ParseTreeNode(other) {}
ParseTreeNode::Ptr clone() const { return Ptr(new DestructorNameNode(*this)); }
void parse(); void parse();
QByteArray description() const { return "DesctuctorName"; }
}; };
class UnresolvedQualifierLevelRule class UnresolvedQualifierLevelRule
{ {
public: public:
static bool mangledRepresentationStartsWith(char c); static bool mangledRepresentationStartsWith(char c);
static void parse(GlobalParseState *parseState, ParseTreeNode *parentNode); static void parse(GlobalParseState *parseState);
private: private:
UnresolvedQualifierLevelRule(); UnresolvedQualifierLevelRule();
@@ -646,12 +776,15 @@ private:
class BaseUnresolvedNameNode : public ParseTreeNode class BaseUnresolvedNameNode : public ParseTreeNode
{ {
public: public:
BaseUnresolvedNameNode(GlobalParseState *parseState);
static bool mangledRepresentationStartsWith(char c); static bool mangledRepresentationStartsWith(char c);
QByteArray toByteArray() const; QByteArray toByteArray() const;
private: private:
BaseUnresolvedNameNode(const BaseUnresolvedNameNode &other);
ParseTreeNode::Ptr clone() const { return Ptr(new BaseUnresolvedNameNode(*this)); }
void parse(); void parse();
QByteArray description() const;
bool m_isOperator; bool m_isOperator;
}; };
@@ -659,23 +792,29 @@ private:
class InitializerNode : public ParseTreeNode class InitializerNode : public ParseTreeNode
{ {
public: public:
InitializerNode(GlobalParseState *parseState) : ParseTreeNode(parseState) {}
static bool mangledRepresentationStartsWith(char c); static bool mangledRepresentationStartsWith(char c);
QByteArray toByteArray() const; QByteArray toByteArray() const;
private: private:
InitializerNode(const InitializerNode &other) : ParseTreeNode(other) {}
ParseTreeNode::Ptr clone() const { return Ptr(new InitializerNode(*this)); }
void parse(); void parse();
QByteArray description() const { return "Initializer"; }
}; };
class UnresolvedNameNode : public ParseTreeNode class UnresolvedNameNode : public ParseTreeNode
{ {
public: public:
UnresolvedNameNode(GlobalParseState *parseState) : ParseTreeNode(parseState) {}
static bool mangledRepresentationStartsWith(char c); static bool mangledRepresentationStartsWith(char c);
QByteArray toByteArray() const; QByteArray toByteArray() const;
private: private:
UnresolvedNameNode(const UnresolvedNameNode &other);
ParseTreeNode::Ptr clone() const { return Ptr(new UnresolvedNameNode(*this)); }
void parse(); void parse();
QByteArray description() const;
bool m_globalNamespace; bool m_globalNamespace;
}; };
@@ -683,12 +822,15 @@ private:
class FunctionParamNode : public ParseTreeNode class FunctionParamNode : public ParseTreeNode
{ {
public: public:
FunctionParamNode(GlobalParseState *parseState) : ParseTreeNode(parseState) {}
static bool mangledRepresentationStartsWith(char c); static bool mangledRepresentationStartsWith(char c);
QByteArray toByteArray() const; QByteArray toByteArray() const;
private: private:
FunctionParamNode(const FunctionParamNode &other) : ParseTreeNode(other) {}
ParseTreeNode::Ptr clone() const { return Ptr(new FunctionParamNode(*this)); }
void parse(); void parse();
QByteArray description() const { return "FunctionParam"; }
}; };
} // namespace Internal } // namespace Internal

View File

@@ -177,10 +177,9 @@ void NameDemanglerAutoTest::testCorrectlyMangledNames()
TEST_CORRECTLY_MANGLED_NAME("_Z8toStringIiESsT_", TEST_CORRECTLY_MANGLED_NAME("_Z8toStringIiESsT_",
"std::basic_string<char, std::char_traits<char>, std::allocator<char> > toString<int>(int)"); "std::basic_string<char, std::char_traits<char>, std::allocator<char> > toString<int>(int)");
// TODO: The rvalue reference at the end has to actually collapse. Remove it once collapsing TEST_CORRECTLY_MANGLED_NAME("_Z4funcIRA5_iEvOT_", "void func<int (&)[5]>(int (&)[5])");
// is properly implemented.
TEST_CORRECTLY_MANGLED_NAME("_ZSt9make_pairIiRA5_KcESt4pairINSt17__decay_and_stripIT_E6__typeENS4_IT0_E6__typeEEOS5_OS8_", TEST_CORRECTLY_MANGLED_NAME("_ZSt9make_pairIiRA5_KcESt4pairINSt17__decay_and_stripIT_E6__typeENS4_IT0_E6__typeEEOS5_OS8_",
"std::pair<std::__decay_and_strip<int>::__type, std::__decay_and_strip<char const (&)[5]>::__type> std::make_pair<int, char const (&)[5]>(int &&, char const (&)[5] &&)"); "std::pair<std::__decay_and_strip<int>::__type, std::__decay_and_strip<char const (&)[5]>::__type> std::make_pair<int, char const (&)[5]>(int &&, char const (&)[5])");
// All examples from the ABI spec. // All examples from the ABI spec.
TEST_CORRECTLY_MANGLED_NAME("_ZN1S1xE", "S::x"); TEST_CORRECTLY_MANGLED_NAME("_ZN1S1xE", "S::x");
@@ -257,15 +256,11 @@ void NameDemanglerAutoTest::testDisjunctFirstSets()
QVERIFY(!TemplateParamNode::mangledRepresentationStartsWith(c) QVERIFY(!TemplateParamNode::mangledRepresentationStartsWith(c)
|| !SubstitutionNode::mangledRepresentationStartsWith(c)); || !SubstitutionNode::mangledRepresentationStartsWith(c));
QVERIFY(!TemplateArgsNode::mangledRepresentationStartsWith(c) QVERIFY(!TemplateArgsNode::mangledRepresentationStartsWith(c)
|| !Prefix2Node::mangledRepresentationStartsWith(c)); || !UnqualifiedNameNode::mangledRepresentationStartsWith(c));
QVERIFY(!TemplateParamNode::mangledRepresentationStartsWith(c) QVERIFY(!TemplateParamNode::mangledRepresentationStartsWith(c)
|| !Prefix2Node::mangledRepresentationStartsWith(c)); || !UnqualifiedNameNode::mangledRepresentationStartsWith(c));
QVERIFY(!SubstitutionNode::mangledRepresentationStartsWith(c) QVERIFY(!SubstitutionNode::mangledRepresentationStartsWith(c)
|| !Prefix2Node::mangledRepresentationStartsWith(c)); || !UnqualifiedNameNode::mangledRepresentationStartsWith(c));
// <prefix2>
QVERIFY(!TemplateArgsNode::mangledRepresentationStartsWith(c)
|| !Prefix2Node::mangledRepresentationStartsWith(c));
// <template-arg> // <template-arg>
QVERIFY(!TypeNode::mangledRepresentationStartsWith(c) QVERIFY(!TypeNode::mangledRepresentationStartsWith(c)
@@ -515,9 +510,9 @@ void NameDemanglerAutoTest::testDisjunctFirstSets()
// <unscoped-name> // <unscoped-name>
QVERIFY(!UnqualifiedNameNode::mangledRepresentationStartsWith('S')); QVERIFY(!UnqualifiedNameNode::mangledRepresentationStartsWith('S'));
// <prefix2> // <prefix>
QVERIFY(!TemplateArgsNode::mangledRepresentationStartsWith('M')); QVERIFY(!TemplateArgsNode::mangledRepresentationStartsWith('M'));
QVERIFY(!Prefix2Node::mangledRepresentationStartsWith('M')); QVERIFY(!UnqualifiedNameNode::mangledRepresentationStartsWith('M'));
// <base-unresolved-name> // <base-unresolved-name>
QVERIFY(!SimpleIdNode::mangledRepresentationStartsWith('o')); QVERIFY(!SimpleIdNode::mangledRepresentationStartsWith('o'));