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

View File

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

View File

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

View File

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

View File

@@ -177,10 +177,9 @@ void NameDemanglerAutoTest::testCorrectlyMangledNames()
TEST_CORRECTLY_MANGLED_NAME("_Z8toStringIiESsT_",
"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
// is properly implemented.
TEST_CORRECTLY_MANGLED_NAME("_Z4funcIRA5_iEvOT_", "void func<int (&)[5]>(int (&)[5])");
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.
TEST_CORRECTLY_MANGLED_NAME("_ZN1S1xE", "S::x");
@@ -257,15 +256,11 @@ void NameDemanglerAutoTest::testDisjunctFirstSets()
QVERIFY(!TemplateParamNode::mangledRepresentationStartsWith(c)
|| !SubstitutionNode::mangledRepresentationStartsWith(c));
QVERIFY(!TemplateArgsNode::mangledRepresentationStartsWith(c)
|| !Prefix2Node::mangledRepresentationStartsWith(c));
|| !UnqualifiedNameNode::mangledRepresentationStartsWith(c));
QVERIFY(!TemplateParamNode::mangledRepresentationStartsWith(c)
|| !Prefix2Node::mangledRepresentationStartsWith(c));
|| !UnqualifiedNameNode::mangledRepresentationStartsWith(c));
QVERIFY(!SubstitutionNode::mangledRepresentationStartsWith(c)
|| !Prefix2Node::mangledRepresentationStartsWith(c));
// <prefix2>
QVERIFY(!TemplateArgsNode::mangledRepresentationStartsWith(c)
|| !Prefix2Node::mangledRepresentationStartsWith(c));
|| !UnqualifiedNameNode::mangledRepresentationStartsWith(c));
// <template-arg>
QVERIFY(!TypeNode::mangledRepresentationStartsWith(c)
@@ -515,9 +510,9 @@ void NameDemanglerAutoTest::testDisjunctFirstSets()
// <unscoped-name>
QVERIFY(!UnqualifiedNameNode::mangledRepresentationStartsWith('S'));
// <prefix2>
// <prefix>
QVERIFY(!TemplateArgsNode::mangledRepresentationStartsWith('M'));
QVERIFY(!Prefix2Node::mangledRepresentationStartsWith('M'));
QVERIFY(!UnqualifiedNameNode::mangledRepresentationStartsWith('M'));
// <base-unresolved-name>
QVERIFY(!SimpleIdNode::mangledRepresentationStartsWith('o'));