diff options
author | Christian Kandeler <christian.kandeler@nokia.com> | 2012-08-10 16:46:38 +0200 |
---|---|---|
committer | Christian Kandeler <christian.kandeler@nokia.com> | 2012-08-13 12:30:10 +0200 |
commit | 26c4329f74b732a397c37b5c416a7ecec407dece (patch) | |
tree | 81af473ae8cb412a7617ade52b259be45dd90fc8 /src/plugins/debugger/namedemangler | |
parent | 2dc005cae73b8268202956587ba5fbd38247679f (diff) | |
download | qt-creator-26c4329f74b732a397c37b5c416a7ecec407dece.tar.gz |
Name demangler: Fix reference collapsing.
Change-Id: I7bcf1ace346ffcb5e05242f6cedfc5439c97fff9
Reviewed-by: Christian Kandeler <christian.kandeler@nokia.com>
Diffstat (limited to 'src/plugins/debugger/namedemangler')
6 files changed, 727 insertions, 366 deletions
diff --git a/src/plugins/debugger/namedemangler/demanglerexceptions.h b/src/plugins/debugger/namedemangler/demanglerexceptions.h index 7c35edcba2..815801085e 100644 --- a/src/plugins/debugger/namedemangler/demanglerexceptions.h +++ b/src/plugins/debugger/namedemangler/demanglerexceptions.h @@ -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; diff --git a/src/plugins/debugger/namedemangler/globalparsestate.cpp b/src/plugins/debugger/namedemangler/globalparsestate.cpp index c9841a1471..3b9b7b1084 100644 --- a/src/plugins/debugger/namedemangler/globalparsestate.cpp +++ b/src/plugins/debugger/namedemangler/globalparsestate.cpp @@ -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 diff --git a/src/plugins/debugger/namedemangler/globalparsestate.h b/src/plugins/debugger/namedemangler/globalparsestate.h index efbdaef12d..4a740ba5e4 100644 --- a/src/plugins/debugger/namedemangler/globalparsestate.h +++ b/src/plugins/debugger/namedemangler/globalparsestate.h @@ -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 = '$'; }; diff --git a/src/plugins/debugger/namedemangler/namedemangler.cpp b/src/plugins/debugger/namedemangler/namedemangler.cpp index 2414b2f0ba..09becca5a4 100644 --- a/src/plugins/debugger/namedemangler/namedemangler.cpp +++ b/src/plugins/debugger/namedemangler/namedemangler.cpp @@ -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(); diff --git a/src/plugins/debugger/namedemangler/parsetreenodes.cpp b/src/plugins/debugger/namedemangler/parsetreenodes.cpp index 66f37a8a4b..65e7f96fe1 100644 --- a/src/plugins/debugger/namedemangler/parsetreenodes.cpp +++ b/src/plugins/debugger/namedemangler/parsetreenodes.cpp @@ -31,6 +31,7 @@ #include "demanglerexceptions.h" +#include <iostream> #include <cctype> #include <cstring> @@ -41,7 +42,7 @@ do { \ ParseTreeNode::parseRule<NodeType>(parseState); \ DEMANGLER_ASSERT(parseState->stackElementCount() > 0); \ - DEMANGLER_ASSERT(dynamic_cast<NodeType *>(parseState->stackTop())); \ + DEMANGLER_ASSERT(parseState->stackTop().dynamicCast<NodeType>()); \ if (parentNode) \ (parentNode)->addChild(parseState->popFromStack()); \ } while (0) @@ -59,20 +60,23 @@ namespace Internal { template<int base> static int getNonNegativeNumber(GlobalParseState *parseState) { ParseTreeNode::parseRule<NonNegativeNumberNode<base> >(parseState); - NonNegativeNumberNode<base> * const numberNode + const typename NonNegativeNumberNode<base>::Ptr numberNode = DEMANGLER_CAST(NonNegativeNumberNode<base>, parseState->popFromStack()); const int value = static_cast<int>(numberNode->number()); - delete numberNode; return value; } +ParseTreeNode::ParseTreeNode(const ParseTreeNode &other) : m_parseState(other.m_parseState) +{ + foreach (const ParseTreeNode::Ptr &child, other.m_children) + addChild(child->clone()); +} ParseTreeNode::~ParseTreeNode() { - qDeleteAll(m_children); } -ParseTreeNode *ParseTreeNode::childAt(int i, const QString &func, const QString &file, +ParseTreeNode::Ptr ParseTreeNode::childAt(int i, const QString &func, const QString &file, int line) const { if (i < 0 || i >= m_children.count()) @@ -83,11 +87,24 @@ ParseTreeNode *ParseTreeNode::childAt(int i, const QString &func, const QString QByteArray ParseTreeNode::pasteAllChildren() const { QByteArray repr; - foreach (const ParseTreeNode * const node, m_children) + foreach (const ParseTreeNode::Ptr &node, m_children) repr += node->toByteArray(); return repr; } +void ParseTreeNode::print(int indentation) const +{ + for (int i = 0; i < indentation; ++i) + std::cerr << ' '; + std::cerr << description().data() << std::endl; + foreach (const ParseTreeNode::Ptr &n, m_children) + n->print(indentation + 2); +} + +QByteArray ParseTreeNode::bool2String(bool b) const +{ + return b ? "true" : "false"; +} bool ArrayTypeNode::mangledRepresentationStartsWith(char c) { @@ -133,6 +150,16 @@ QByteArray ArrayTypeNode::toByteArray() const } +BareFunctionTypeNode::BareFunctionTypeNode(GlobalParseState *parseState) + : ParseTreeNode(parseState), m_hasReturnType(false) +{ +} + +BareFunctionTypeNode::BareFunctionTypeNode(const BareFunctionTypeNode &other) + : ParseTreeNode(other), m_hasReturnType(other.hasReturnType()) +{ +} + bool BareFunctionTypeNode::mangledRepresentationStartsWith(char c) { return TypeNode::mangledRepresentationStartsWith(c); @@ -154,10 +181,10 @@ void BareFunctionTypeNode::parse() * The exceptions mentioned in (1) and (2) above, for which the return type is never included, * are constructors, destructors and conversion operator functions, e.g. operator int. */ - const EncodingNode * const encodingNode = dynamic_cast<EncodingNode *>(parseState() - ->stackElementAt(parseState()->stackElementCount() - 2)); + const EncodingNode::Ptr encodingNode = parseState()->stackElementAt(parseState() + ->stackElementCount() - 2).dynamicCast<EncodingNode>(); if (encodingNode) { // Case 1: Function name. - const NameNode * const nameNode = DEMANGLER_CAST(NameNode, CHILD_AT(encodingNode, 0)); + const NameNode::Ptr nameNode = DEMANGLER_CAST(NameNode, CHILD_AT(encodingNode, 0)); m_hasReturnType = nameNode->isTemplate() && !nameNode->isConstructorOrDestructorOrConversionOperator(); } else { // Case 2: function type. @@ -170,6 +197,16 @@ void BareFunctionTypeNode::parse() while (TypeNode::mangledRepresentationStartsWith(PEEK())); } +QByteArray BareFunctionTypeNode::description() const +{ + QByteArray desc = "BareFunctionType"; + if (m_hasReturnType) + desc += "[with return type]"; + else + desc += "[without return type]"; + return desc; +} + QByteArray BareFunctionTypeNode::toByteArray() const { // This is only the parameter list, including parentheses. Where the return type is placed @@ -186,6 +223,11 @@ QByteArray BareFunctionTypeNode::toByteArray() const } +BuiltinTypeNode::BuiltinTypeNode(const BuiltinTypeNode &other) + : ParseTreeNode(other), m_type(other.type()) +{ +} + bool BuiltinTypeNode::mangledRepresentationStartsWith(char c) { return strchr("vwbcahstijlmxynofgedzDu", c); @@ -229,7 +271,7 @@ void BuiltinTypeNode::parse() if (next == 'u') { m_type = VendorType; PARSE_RULE_AND_ADD_RESULT_AS_CHILD(SourceNameNode); - parseState()->addSubstitution(this); + parseState()->addSubstitution(parseState()->stackTop()); return; } @@ -280,6 +322,11 @@ void BuiltinTypeNode::parse() } } +QByteArray BuiltinTypeNode::description() const +{ + return "BuiltinType[" + toByteArray() + ']'; +} + QByteArray BuiltinTypeNode::toByteArray() const { switch (m_type) { @@ -329,8 +376,9 @@ bool CallOffsetRule::mangledRepresentationStartsWith(char c) * <call-offset> ::= h <nv-offset> _ * ::= v <v-offset> _ */ -void CallOffsetRule::parse(GlobalParseState *parseState, ParseTreeNode *parentNode) +void CallOffsetRule::parse(GlobalParseState *parseState) { + const ParseTreeNode::Ptr parentNode = parseState->stackTop(); switch (parseState->advance()) { case 'h': PARSE_RULE_AND_ADD_RESULT_AS_CHILD_TO_NODE(NvOffsetNode, parseState, parentNode); break; case 'v': PARSE_RULE_AND_ADD_RESULT_AS_CHILD_TO_NODE(VOffsetNode, parseState, parentNode); break; @@ -352,9 +400,9 @@ bool ClassEnumTypeRule::mangledRepresentationStartsWith(char c) } /* <class-enum-type> ::= <name> */ -void ClassEnumTypeRule::parse(GlobalParseState *parseState, ParseTreeNode *parentNode) +void ClassEnumTypeRule::parse(GlobalParseState *parseState) { - PARSE_RULE_AND_ADD_RESULT_AS_CHILD_TO_NODE(NameNode, parseState, parentNode); + PARSE_RULE_AND_ADD_RESULT_AS_CHILD_TO_NODE(NameNode, parseState, parseState->stackTop()); } @@ -368,7 +416,7 @@ bool DiscriminatorRule::mangledRepresentationStartsWith(char c) * <discriminator> := _ <non-negative number> # when number < 10 * := __ <non-negative number> _ # when number >= 10 */ -void DiscriminatorRule::parse(GlobalParseState *parseState, ParseTreeNode *parentNode) +void DiscriminatorRule::parse(GlobalParseState *parseState) { if (parseState->advance() != '_') throw ParseException(QString::fromLatin1("Invalid discriminator")); @@ -377,8 +425,9 @@ void DiscriminatorRule::parse(GlobalParseState *parseState, ParseTreeNode *paren ge10 = true; parseState->advance(); } + const ParseTreeNode::Ptr parentNode = parseState->stackTop(); PARSE_RULE_AND_ADD_RESULT_AS_CHILD_TO_NODE(NonNegativeNumberNode<10>, parseState, parentNode); - const NonNegativeNumberNode<10> * const number + const NonNegativeNumberNode<10>::Ptr number = DEMANGLER_CAST(NonNegativeNumberNode<10>, CHILD_AT(parentNode, parentNode->childCount() - 1)); if ((ge10 && number->number() < 10) || (!ge10 && number->number() >= 10)) throw ParseException(QString::fromLatin1("Invalid discriminator")); @@ -387,6 +436,13 @@ void DiscriminatorRule::parse(GlobalParseState *parseState, ParseTreeNode *paren } +CtorDtorNameNode::CtorDtorNameNode(const CtorDtorNameNode &other) + : ParseTreeNode(other), + m_isDestructor(other.m_isDestructor), + m_representation(other.m_representation) +{ +} + bool CtorDtorNameNode::mangledRepresentationStartsWith(char c) { return c == 'C' || c == 'D'; @@ -419,7 +475,13 @@ void CtorDtorNameNode::parse() throw ParseException(QString::fromLatin1("Invalid ctor-dtor-name")); } - m_representation = parseState()->substitutionAt(parseState()->substitutionCount() - 1); + m_representation = parseState()->substitutionAt(parseState()->substitutionCount() - 1)->toByteArray(); +} + +QByteArray CtorDtorNameNode::description() const +{ + return "CtorDtor[isDestructor:" + bool2String(m_isDestructor) + + ";repr=" + m_representation + ']'; } QByteArray CtorDtorNameNode::toByteArray() const @@ -437,6 +499,16 @@ QByteArray CtorDtorNameNode::toByteArray() const } +CvQualifiersNode::CvQualifiersNode(GlobalParseState *parseState) + : ParseTreeNode(parseState), m_hasConst(false), m_hasVolatile(false) +{ +} + +CvQualifiersNode::CvQualifiersNode(const CvQualifiersNode &other) + : ParseTreeNode(other), m_hasConst(other.m_hasConst), m_hasVolatile(other.m_hasVolatile) +{ +} + bool CvQualifiersNode::mangledRepresentationStartsWith(char c) { return c == 'K' || c == 'V' || c == 'r'; @@ -445,9 +517,6 @@ bool CvQualifiersNode::mangledRepresentationStartsWith(char c) /* <CV-qualifiers> ::= [r] [V] [K] # restrict (C99), volatile, const */ void CvQualifiersNode::parse() { - m_hasConst = false; - m_hasVolatile = false; - while (true) { if (PEEK() == 'V') { if (hasQualifiers()) @@ -497,7 +566,7 @@ void EncodingNode::parse() PARSE_RULE_AND_ADD_RESULT_AS_CHILD(NameNode); if (BareFunctionTypeNode::mangledRepresentationStartsWith(PEEK())) PARSE_RULE_AND_ADD_RESULT_AS_CHILD(BareFunctionTypeNode); - parseState()->addSubstitution(this); + parseState()->addSubstitution(parseState()->stackTop()); } else if (SpecialNameNode::mangledRepresentationStartsWith(next)) { PARSE_RULE_AND_ADD_RESULT_AS_CHILD(SpecialNameNode); } else { @@ -510,13 +579,13 @@ QByteArray EncodingNode::toByteArray() const if (childCount() == 1) return CHILD_TO_BYTEARRAY(0); - const ParseTreeNode * const firstChild = MY_CHILD_AT(0); - const NameNode * const nameNode = dynamic_cast<const NameNode *>(firstChild); - const CvQualifiersNode * const cvQualifiersNode = nameNode ? nameNode->cvQualifiers() : 0; + const ParseTreeNode::Ptr firstChild = MY_CHILD_AT(0); + const NameNode::Ptr nameNode = firstChild.dynamicCast<NameNode>(); + const CvQualifiersNode::Ptr cvQualifiersNode + = nameNode ? nameNode->cvQualifiers() : CvQualifiersNode::Ptr(); QByteArray repr; - const BareFunctionTypeNode * const funcNode - = DEMANGLER_CAST(BareFunctionTypeNode, MY_CHILD_AT(1)); + const BareFunctionTypeNode::Ptr funcNode = DEMANGLER_CAST(BareFunctionTypeNode, MY_CHILD_AT(1)); if (funcNode->hasReturnType()) repr = CHILD_AT(funcNode, 0)->toByteArray() + ' '; if (cvQualifiersNode && cvQualifiersNode->hasQualifiers()) { @@ -527,6 +596,16 @@ QByteArray EncodingNode::toByteArray() const } +ExpressionNode::ExpressionNode(GlobalParseState *parseState) + : ParseTreeNode(parseState), m_type(OtherType), m_globalNamespace(false) +{ +} + +ExpressionNode::ExpressionNode(const ExpressionNode &other) + : ParseTreeNode(other), m_type(other.m_type), m_globalNamespace(other.m_globalNamespace) +{ +} + bool ExpressionNode::mangledRepresentationStartsWith(char c) { return OperatorNameNode::mangledRepresentationStartsWith(c) @@ -576,9 +655,6 @@ bool ExpressionNode::mangledRepresentationStartsWith(char c) */ void ExpressionNode::parse() { - m_type = OtherType; - m_globalNamespace = false; - /* * Some of the terminals in the productions of <expression> * also appear in the productions of <operator-name>. The direct @@ -699,7 +775,7 @@ void ExpressionNode::parse() && str != "gs" && str != "sr") { m_type = OperatorType; PARSE_RULE_AND_ADD_RESULT_AS_CHILD(OperatorNameNode); - OperatorNameNode * const opNode + const OperatorNameNode::Ptr opNode = DEMANGLER_CAST(OperatorNameNode, MY_CHILD_AT(childCount() - 1)); int expressionCount; @@ -749,6 +825,12 @@ void ExpressionNode::parse() } } +QByteArray ExpressionNode::description() const +{ + return "Expression[global:" + bool2String(m_globalNamespace) + + ";type:" + QByteArray::number(m_type) + ']'; +} + QByteArray ExpressionNode::toByteArray() const { QByteArray repr; @@ -773,7 +855,7 @@ QByteArray ExpressionNode::toByteArray() const QByteArray exprList; int i = 0; for (; i < childCount(); ++i) { - if (!dynamic_cast<ExpressionNode *>(MY_CHILD_AT(i))) + if (!MY_CHILD_AT(i).dynamicCast<ExpressionNode>()) break; if (i > 0) repr += ", "; @@ -844,7 +926,7 @@ QByteArray ExpressionNode::toByteArray() const repr.append("throw"); break; case OperatorType: { - const OperatorNameNode * const opNode = DEMANGLER_CAST(OperatorNameNode, MY_CHILD_AT(0)); + const OperatorNameNode::Ptr opNode = DEMANGLER_CAST(OperatorNameNode, MY_CHILD_AT(0)); switch (opNode->type()) { case OperatorNameNode::CallType: repr = CHILD_TO_BYTEARRAY(1) + opNode->toByteArray(); @@ -914,6 +996,11 @@ QByteArray ExpressionNode::toByteArray() const } +OperatorNameNode::OperatorNameNode(const OperatorNameNode &other) + : ParseTreeNode(other), m_type(other.m_type) +{ +} + bool OperatorNameNode::mangledRepresentationStartsWith(char c) { return strchr("ndpacmroelgiqsv", c); @@ -1099,6 +1186,11 @@ void OperatorNameNode::parse() } } +QByteArray OperatorNameNode::description() const +{ + return "OperatorName[type:" + toByteArray() + ']'; +} + QByteArray OperatorNameNode::toByteArray() const { switch (m_type) { @@ -1155,6 +1247,17 @@ QByteArray OperatorNameNode::toByteArray() const return QByteArray(); } + +ExprPrimaryNode::ExprPrimaryNode(GlobalParseState *parseState) + : ParseTreeNode(parseState), m_isNullPtr(false) +{ +} + +ExprPrimaryNode::ExprPrimaryNode(const ExprPrimaryNode &other) + : ParseTreeNode(other), m_suffix(other.m_suffix), m_isNullPtr(other.m_isNullPtr) +{ +} + bool ExprPrimaryNode::mangledRepresentationStartsWith(char c) { return c == 'L'; @@ -1173,13 +1276,13 @@ void ExprPrimaryNode::parse() { if (!ExprPrimaryNode::mangledRepresentationStartsWith(ADVANCE())) throw ParseException(QString::fromLatin1("Invalid primary expression")); - m_isNullPtr = false; - bool needsESuffix = true; + bool needsSuffix = true; const char next = PEEK(); if (TypeNode::mangledRepresentationStartsWith(next)) { - const ParseTreeNode * const topLevelTypeNode = parseRule<TypeNode>(parseState()); - BuiltinTypeNode * const typeNode = topLevelTypeNode->childCount() == 0 - ? 0 : dynamic_cast<BuiltinTypeNode * >(CHILD_AT(topLevelTypeNode, 0)); + const ParseTreeNode::Ptr topLevelTypeNode = parseRule<TypeNode>(parseState()); + const BuiltinTypeNode::Ptr typeNode = topLevelTypeNode->childCount() == 0 + ? BuiltinTypeNode::Ptr() + : CHILD_AT(topLevelTypeNode, 0).dynamicCast<BuiltinTypeNode>(); if (!typeNode) throw ParseException(QLatin1String("Invalid type in expr-primary")); @@ -1213,21 +1316,26 @@ void ExprPrimaryNode::parse() break; case BuiltinTypeNode::PlainCharType: case BuiltinTypeNode::WCharType: case BuiltinTypeNode::Char16Type: case BuiltinTypeNode::Char32Type: - needsESuffix = false; + needsSuffix = false; break; // string type default: throw ParseException(QString::fromLatin1("Invalid type in expr-primary")); } - delete parseState()->popFromStack(); // No need to keep the type node in the tree. + parseState()->popFromStack(); // No need to keep the type node in the tree. } else if (MangledNameRule::mangledRepresentationStartsWith(next)) { - MangledNameRule::parse(parseState(), this); + MangledNameRule::parse(parseState(), parseState()->stackTop()); } else { throw ParseException(QString::fromLatin1("Invalid expr-primary")); } - if (needsESuffix && ADVANCE() != 'E') + if (needsSuffix && ADVANCE() != 'E') throw ParseException(QString::fromLatin1("Invalid expr-primary")); } +QByteArray ExprPrimaryNode::description() const +{ + return "ExprPrimary[m_suffix:" + m_suffix + ";m_isNullPtr:" + bool2String(m_isNullPtr) + ']'; +} + QByteArray ExprPrimaryNode::toByteArray() const { if (m_isNullPtr) @@ -1235,6 +1343,17 @@ QByteArray ExprPrimaryNode::toByteArray() const return CHILD_TO_BYTEARRAY(0) + m_suffix; } + +FunctionTypeNode::FunctionTypeNode(GlobalParseState *parseState) + : ParseTreeNode(parseState), m_isExternC(false) +{ +} + +FunctionTypeNode::FunctionTypeNode(const FunctionTypeNode &other) + : ParseTreeNode(other), m_isExternC(other.isExternC()) +{ +} + bool FunctionTypeNode::mangledRepresentationStartsWith(char c) { return c == 'F'; @@ -1249,8 +1368,6 @@ void FunctionTypeNode::parse() if (PEEK() == 'Y') { ADVANCE(); m_isExternC = true; - } else { - m_isExternC = false; } PARSE_RULE_AND_ADD_RESULT_AS_CHILD(BareFunctionTypeNode); @@ -1258,12 +1375,29 @@ void FunctionTypeNode::parse() throw ParseException(QString::fromLatin1("Invalid function type")); } +QByteArray FunctionTypeNode::description() const +{ + return "FunctionType[isExternC:" + bool2String(m_isExternC) + ']'; +} + QByteArray FunctionTypeNode::toByteArray() const { return QByteArray(); // Not enough knowledge here to generate a string representation. } +LocalNameNode::LocalNameNode(GlobalParseState *parseState) + : ParseTreeNode(parseState), m_isStringLiteral(false), m_isDefaultArg(false) +{ +} + +LocalNameNode::LocalNameNode(const LocalNameNode &other) + : ParseTreeNode(other), + m_isStringLiteral(other.m_isStringLiteral), + m_isDefaultArg(other.m_isDefaultArg) +{ +} + bool LocalNameNode::mangledRepresentationStartsWith(char c) { return c == 'Z'; @@ -1283,9 +1417,6 @@ void LocalNameNode::parse() if (!mangledRepresentationStartsWith(ADVANCE())) throw ParseException(QString::fromLatin1("Invalid local-name")); - m_isStringLiteral = false; - m_isDefaultArg = false; - PARSE_RULE_AND_ADD_RESULT_AS_CHILD(EncodingNode); if (ADVANCE() != 'E') @@ -1311,7 +1442,13 @@ void LocalNameNode::parse() throw ParseException(QString::fromLatin1("Invalid local-name")); } if (DiscriminatorRule::mangledRepresentationStartsWith(PEEK())) - DiscriminatorRule::parse(parseState(), this); + DiscriminatorRule::parse(parseState()); +} + +QByteArray LocalNameNode::description() const +{ + return "LocalName[isStringLiteral:" + bool2String(m_isStringLiteral) + ";isDefaultArg:" + + bool2String(m_isDefaultArg) + ']'; } QByteArray LocalNameNode::toByteArray() const @@ -1319,13 +1456,13 @@ QByteArray LocalNameNode::toByteArray() const QByteArray name; bool hasDiscriminator; if (m_isDefaultArg) { - const ParseTreeNode * const encodingNode = MY_CHILD_AT(0); - const BareFunctionTypeNode * const funcNode + const ParseTreeNode::Ptr encodingNode = MY_CHILD_AT(0); + const BareFunctionTypeNode::Ptr funcNode = DEMANGLER_CAST(BareFunctionTypeNode, CHILD_AT(encodingNode, 1)); const int functionParamCount = funcNode->hasReturnType() ? funcNode->childCount() - 1 : funcNode->childCount(); - const NonNegativeNumberNode<10> * const numberNode - = dynamic_cast<NonNegativeNumberNode<10> *>(MY_CHILD_AT(1)); + const typename NonNegativeNumberNode<10>::Ptr numberNode + = MY_CHILD_AT(1).dynamicCast<NonNegativeNumberNode<10> >(); // "_" means last argument, "n" means (n+1)th to last. // Note that c++filt in binutils 2.22 does this wrong. @@ -1353,25 +1490,25 @@ QByteArray LocalNameNode::toByteArray() const bool LocalNameNode::isTemplate() const { - if (childCount() == 1 || dynamic_cast<NonNegativeNumberNode<10> *>(MY_CHILD_AT(1))) + if (childCount() == 1 || MY_CHILD_AT(1).dynamicCast<NonNegativeNumberNode<10> >()) return false; return DEMANGLER_CAST(NameNode, MY_CHILD_AT(1))->isTemplate(); } bool LocalNameNode::isConstructorOrDestructorOrConversionOperator() const { - if (childCount() == 1 || dynamic_cast<NonNegativeNumberNode<10> *>(MY_CHILD_AT(1))) + if (childCount() == 1 || MY_CHILD_AT(1).dynamicCast<NonNegativeNumberNode<10> >()) return false; return DEMANGLER_CAST(NameNode, MY_CHILD_AT(1))->isConstructorOrDestructorOrConversionOperator(); } -const CvQualifiersNode *LocalNameNode::cvQualifiers() const +CvQualifiersNode::Ptr LocalNameNode::cvQualifiers() const { if (m_isDefaultArg) - return DEMANGLER_CAST(const NameNode, MY_CHILD_AT(childCount() - 1))->cvQualifiers(); - if (childCount() == 1 || dynamic_cast<NonNegativeNumberNode<10> *>(MY_CHILD_AT(1))) - return 0; - return DEMANGLER_CAST(const NameNode, MY_CHILD_AT(1))->cvQualifiers(); + return DEMANGLER_CAST(NameNode, MY_CHILD_AT(childCount() - 1))->cvQualifiers(); + if (childCount() == 1 || MY_CHILD_AT(1).dynamicCast<NonNegativeNumberNode<10> >()) + return CvQualifiersNode::Ptr(); + return DEMANGLER_CAST(NameNode, MY_CHILD_AT(1))->cvQualifiers(); } @@ -1386,13 +1523,18 @@ bool MangledNameRule::mangledRepresentationStartsWith(char c) * were necessary, which we will document at the respective parsing function. * <mangled-name> ::= _Z <encoding> */ -void MangledNameRule::parse(GlobalParseState *parseState, ParseTreeNode *parentNode) +void MangledNameRule::parse(GlobalParseState *parseState, const ParseTreeNode::Ptr &parentNode) { parseState->advance(2); PARSE_RULE_AND_ADD_RESULT_AS_CHILD_TO_NODE(EncodingNode, parseState, parentNode); } +SourceNameNode::SourceNameNode(const SourceNameNode &other) + : ParseTreeNode(other), m_name(other.m_name) +{ +} + bool SourceNameNode::mangledRepresentationStartsWith(char c) { return strchr("123456789", c); @@ -1406,6 +1548,11 @@ void SourceNameNode::parse() parseState()->advance(idLen); } +QByteArray SourceNameNode::description() const +{ + return "SourceName[name:" + m_name + ']'; +} + bool UnqualifiedNameNode::mangledRepresentationStartsWith(char c) { @@ -1418,16 +1565,16 @@ bool UnqualifiedNameNode::mangledRepresentationStartsWith(char c) QByteArray UnqualifiedNameNode::toByteArray() const { QByteArray repr; - if (dynamic_cast<OperatorNameNode *>(MY_CHILD_AT(0))) + if (MY_CHILD_AT(0).dynamicCast<OperatorNameNode>()) repr = "operator"; return repr += CHILD_TO_BYTEARRAY(0); } bool UnqualifiedNameNode::isConstructorOrDestructorOrConversionOperator() const { - if (dynamic_cast<CtorDtorNameNode *>(MY_CHILD_AT(0))) + if (MY_CHILD_AT(0).dynamicCast<CtorDtorNameNode>()) return true; - const OperatorNameNode * const opNode = dynamic_cast<OperatorNameNode *>(MY_CHILD_AT(0)); + const OperatorNameNode::Ptr opNode = MY_CHILD_AT(0).dynamicCast<OperatorNameNode>(); return opNode && opNode->type() == OperatorNameNode::CastType; } @@ -1453,6 +1600,16 @@ void UnqualifiedNameNode::parse() } +UnscopedNameNode::UnscopedNameNode(GlobalParseState *parseState) + : ParseTreeNode(parseState), m_inStdNamespace(false) +{ +} + +UnscopedNameNode::UnscopedNameNode(const UnscopedNameNode &other) + : ParseTreeNode(other), m_inStdNamespace(other.m_inStdNamespace) +{ +} + bool UnscopedNameNode::mangledRepresentationStartsWith(char c) { return UnqualifiedNameNode::mangledRepresentationStartsWith(c) || c == 'S'; @@ -1468,8 +1625,7 @@ QByteArray UnscopedNameNode::toByteArray() const bool UnscopedNameNode::isConstructorOrDestructorOrConversionOperator() const { - const UnqualifiedNameNode * const childNode - = DEMANGLER_CAST(UnqualifiedNameNode, MY_CHILD_AT(0)); + const UnqualifiedNameNode::Ptr childNode = DEMANGLER_CAST(UnqualifiedNameNode, MY_CHILD_AT(0)); return childNode->isConstructorOrDestructorOrConversionOperator(); } @@ -1482,8 +1638,6 @@ void UnscopedNameNode::parse() if (parseState()->readAhead(2) == "St") { m_inStdNamespace = true; parseState()->advance(2); - } else { - m_inStdNamespace = false; } if (!UnqualifiedNameNode::mangledRepresentationStartsWith(PEEK())) @@ -1492,6 +1646,11 @@ void UnscopedNameNode::parse() PARSE_RULE_AND_ADD_RESULT_AS_CHILD(UnqualifiedNameNode); } +QByteArray UnscopedNameNode::description() const +{ + return "UnscopedName[isInStdNamespace:" + bool2String(m_inStdNamespace) + ']'; +} + bool NestedNameNode::mangledRepresentationStartsWith(char c) { @@ -1501,26 +1660,26 @@ bool NestedNameNode::mangledRepresentationStartsWith(char c) QByteArray NestedNameNode::toByteArray() const { // cv-qualifiers are not encoded here, since they only make sense at a higher level. - if (dynamic_cast<CvQualifiersNode *>(MY_CHILD_AT(0))) + if (MY_CHILD_AT(0).dynamicCast<CvQualifiersNode>()) return CHILD_TO_BYTEARRAY(1); return CHILD_TO_BYTEARRAY(0); } bool NestedNameNode::isTemplate() const { - const PrefixNode * const childNode = DEMANGLER_CAST(PrefixNode, MY_CHILD_AT(childCount() - 1)); + const PrefixNode::Ptr 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)); + const PrefixNode::Ptr childNode = DEMANGLER_CAST(PrefixNode, MY_CHILD_AT(childCount() - 1)); return childNode->isConstructorOrDestructorOrConversionOperator(); } -const CvQualifiersNode *NestedNameNode::cvQualifiers() const +CvQualifiersNode::Ptr NestedNameNode::cvQualifiers() const { - return dynamic_cast<CvQualifiersNode *>(MY_CHILD_AT(0)); + return MY_CHILD_AT(0).dynamicCast<CvQualifiersNode>(); } /* @@ -1566,6 +1725,11 @@ void NestedNameNode::parse() } +SubstitutionNode::SubstitutionNode(const SubstitutionNode &other) + : ParseTreeNode(other), m_type(other.type()) +{ +} + bool SubstitutionNode::mangledRepresentationStartsWith(char c) { return c == 'S'; @@ -1598,7 +1762,7 @@ void SubstitutionNode::parse() arg(substIndex + 1).arg(parseState()->substitutionCount())); } m_type = ActualSubstitutionType; - m_substValue = parseState()->substitutionAt(substIndex); + addChild(parseState()->substitutionAt(substIndex)); if (ADVANCE() != '_') throw ParseException(QString::fromLatin1("Invalid substitution")); } else { @@ -1608,13 +1772,13 @@ void SubstitutionNode::parse() throw ParseException(QString::fromLatin1("Invalid substitution: " "There are no substitutions")); m_type = ActualSubstitutionType; - m_substValue = parseState()->substitutionAt(0); + addChild(parseState()->substitutionAt(0)); break; case 't': m_type = StdType; if (UnqualifiedNameNode::mangledRepresentationStartsWith(PEEK())) { PARSE_RULE_AND_ADD_RESULT_AS_CHILD(UnqualifiedNameNode); - parseState()->addSubstitution(this); + parseState()->addSubstitution(parseState()->stackTop()); } break; case 'a': m_type = StdAllocType; break; @@ -1628,10 +1792,15 @@ void SubstitutionNode::parse() } } +QByteArray SubstitutionNode::description() const +{ + return "Substitution[type:" + QByteArray::number(m_type) + ']'; +} + QByteArray SubstitutionNode::toByteArray() const { switch (m_type) { - case ActualSubstitutionType: return m_substValue; + case ActualSubstitutionType: return CHILD_TO_BYTEARRAY(0); case StdType: { QByteArray repr = "std"; if (childCount() > 0) @@ -1669,12 +1838,11 @@ void PointerToMemberTypeNode::parse() QByteArray PointerToMemberTypeNode::toByteArray() const { - // Gather all qualifiers first, because we have to move them to the end en bloc - // . + // 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)); + TypeNode::Ptr memberTypeNode = DEMANGLER_CAST(TypeNode, MY_CHILD_AT(1)); while (memberTypeNode->type() == TypeNode::QualifiedType) { - const CvQualifiersNode * const cvNode + const CvQualifiersNode::Ptr cvNode = DEMANGLER_CAST(CvQualifiersNode, CHILD_AT(memberTypeNode, 0)); if (cvNode->hasQualifiers()) { if (!qualRepr.isEmpty()) @@ -1686,10 +1854,10 @@ QByteArray PointerToMemberTypeNode::toByteArray() const QByteArray repr; const QByteArray classTypeRepr = CHILD_TO_BYTEARRAY(0); - const FunctionTypeNode * const functionNode - = dynamic_cast<const FunctionTypeNode *>(CHILD_AT(memberTypeNode, 0)); + const FunctionTypeNode::Ptr functionNode + = CHILD_AT(memberTypeNode, 0).dynamicCast<FunctionTypeNode>(); if (functionNode) { - const BareFunctionTypeNode * const bareFunctionNode + const BareFunctionTypeNode::Ptr bareFunctionNode = DEMANGLER_CAST(BareFunctionTypeNode, CHILD_AT(functionNode, 0)); if (functionNode->isExternC()) repr += "extern \"C\" "; @@ -1708,9 +1876,9 @@ QByteArray PointerToMemberTypeNode::toByteArray() const } -TemplateParamNode::~TemplateParamNode() +TemplateParamNode::TemplateParamNode(const TemplateParamNode &other) + : ParseTreeNode(other), m_index(other.index()) { - clearChildList(); // Child node is deleted elsewhere. } bool TemplateParamNode::mangledRepresentationStartsWith(char c) @@ -1736,8 +1904,8 @@ void TemplateParamNode::parse() if (m_index >= parseState()->templateParamCount()) { bool isConversionOperator = false; for (int i = parseState()->stackElementCount() - 1; i >= 0; --i) { - const OperatorNameNode * const opNode - = dynamic_cast<OperatorNameNode *>(parseState()->stackElementAt(i)); + const OperatorNameNode::Ptr opNode + = parseState()->stackElementAt(i).dynamicCast<OperatorNameNode>(); if (opNode && opNode->type() == OperatorNameNode::CastType) { isConversionOperator = true; break; @@ -1752,6 +1920,11 @@ void TemplateParamNode::parse() } } +QByteArray TemplateParamNode::description() const +{ + return "TemplateParam[index:" + QByteArray::number(m_index) + ']'; +} + QByteArray TemplateParamNode::toByteArray() const { return CHILD_TO_BYTEARRAY(0); @@ -1791,6 +1964,11 @@ QByteArray TemplateArgsNode::toByteArray() const } +SpecialNameNode::SpecialNameNode(const SpecialNameNode &other) + : ParseTreeNode(other), m_type(other.m_type) +{ +} + bool SpecialNameNode::mangledRepresentationStartsWith(char c) { return c == 'T' || c == 'G'; @@ -1834,18 +2012,23 @@ void SpecialNameNode::parse() } else if (str == "Tc") { m_type = DoubleCallOffsetType; parseState()->advance(2); - CallOffsetRule::parse(parseState(), this); - CallOffsetRule::parse(parseState(), this); + CallOffsetRule::parse(parseState()); + CallOffsetRule::parse(parseState()); PARSE_RULE_AND_ADD_RESULT_AS_CHILD(EncodingNode); } else if (ADVANCE() == 'T') { m_type = SingleCallOffsetType; - CallOffsetRule::parse(parseState(), this); + CallOffsetRule::parse(parseState()); PARSE_RULE_AND_ADD_RESULT_AS_CHILD(EncodingNode); } else { throw ParseException(QString::fromLatin1("Invalid special-name")); } } +QByteArray SpecialNameNode::description() const +{ + return "SpecialName[type:" + QByteArray::number(m_type) + ']'; +} + QByteArray SpecialNameNode::toByteArray() const { switch (m_type) { @@ -1871,6 +2054,16 @@ QByteArray SpecialNameNode::toByteArray() const } +NumberNode::NumberNode(GlobalParseState *parseState) + : ParseTreeNode(parseState), m_isNegative(false) +{ +} + +NumberNode::NumberNode(const NumberNode &other) + : ParseTreeNode(other), m_isNegative(other.m_isNegative) +{ +} + bool NumberNode::mangledRepresentationStartsWith(char c) { return NonNegativeNumberNode<10>::mangledRepresentationStartsWith(c) || c == 'n'; @@ -1886,13 +2079,16 @@ void NumberNode::parse() if (next == 'n') { m_isNegative = true; ADVANCE(); - } else { - m_isNegative = false; } PARSE_RULE_AND_ADD_RESULT_AS_CHILD(NonNegativeNumberNode<10>); } +QByteArray NumberNode::description() const +{ + return "Number[isNegative:" + bool2String(m_isNegative) + ']'; +} + QByteArray NumberNode::toByteArray() const { QByteArray repr = CHILD_TO_BYTEARRAY(0); @@ -1902,6 +2098,11 @@ QByteArray NumberNode::toByteArray() const } +template<int base> NonNegativeNumberNode<base>::NonNegativeNumberNode(const NonNegativeNumberNode<base> &other) + : ParseTreeNode(other), m_number(other.m_number) +{ +} + template<int base> bool NonNegativeNumberNode<base>::mangledRepresentationStartsWith(char c) { // Base can only be 10 or 36. @@ -1921,6 +2122,12 @@ template<int base> void NonNegativeNumberNode<base>::parse() m_number = numberRepr.toULongLong(0, base); } +template<int base> QByteArray NonNegativeNumberNode<base>::description() const +{ + return "NonNegativeNumber[base:" + QByteArray::number(base) + ";number:" + + QByteArray::number(m_number) + ']'; +} + template<int base> QByteArray NonNegativeNumberNode<base>::toByteArray() const { return QByteArray::number(m_number); @@ -1942,12 +2149,12 @@ QByteArray NameNode::toByteArray() const bool NameNode::isTemplate() const { - if (childCount() > 1 && dynamic_cast<TemplateArgsNode *>(MY_CHILD_AT(1))) + if (childCount() > 1 && MY_CHILD_AT(1).dynamicCast<TemplateArgsNode>()) return true; - const NestedNameNode * const nestedNameNode = dynamic_cast<NestedNameNode *>(MY_CHILD_AT(0)); + const NestedNameNode::Ptr nestedNameNode = MY_CHILD_AT(0).dynamicCast<NestedNameNode>(); if (nestedNameNode) return nestedNameNode->isTemplate(); - const LocalNameNode * const localNameNode = dynamic_cast<LocalNameNode *>(MY_CHILD_AT(0)); + const LocalNameNode::Ptr localNameNode = MY_CHILD_AT(0).dynamicCast<LocalNameNode>(); if (localNameNode) return localNameNode->isTemplate(); @@ -1956,25 +2163,25 @@ bool NameNode::isTemplate() const bool NameNode::isConstructorOrDestructorOrConversionOperator() const { - const NestedNameNode * const nestedNameNode = dynamic_cast<NestedNameNode *>(MY_CHILD_AT(0)); + NestedNameNode::Ptr nestedNameNode = MY_CHILD_AT(0).dynamicCast<NestedNameNode>(); if (nestedNameNode) return nestedNameNode->isConstructorOrDestructorOrConversionOperator(); - const LocalNameNode * const localNameNode = dynamic_cast<LocalNameNode *>(MY_CHILD_AT(0)); + const LocalNameNode::Ptr localNameNode = MY_CHILD_AT(0).dynamicCast<LocalNameNode>(); if (localNameNode) return localNameNode->isConstructorOrDestructorOrConversionOperator(); return false; } -const CvQualifiersNode *NameNode::cvQualifiers() const +CvQualifiersNode::Ptr NameNode::cvQualifiers() const { - const NestedNameNode * const nestedNameNode = dynamic_cast<NestedNameNode *>(MY_CHILD_AT(0)); + const NestedNameNode::Ptr nestedNameNode = MY_CHILD_AT(0).dynamicCast<NestedNameNode>(); if (nestedNameNode) return nestedNameNode->cvQualifiers(); - const LocalNameNode * const localNameNode = dynamic_cast<LocalNameNode *>(MY_CHILD_AT(0)); + const LocalNameNode::Ptr localNameNode = MY_CHILD_AT(0).dynamicCast<LocalNameNode>(); if (localNameNode) return localNameNode->cvQualifiers(); - return 0; + return CvQualifiersNode::Ptr(); } /* @@ -1999,7 +2206,7 @@ void NameNode::parse() || UnscopedNameNode::mangledRepresentationStartsWith(PEEK())) { PARSE_RULE_AND_ADD_RESULT_AS_CHILD(UnscopedNameNode); if (TemplateArgsNode::mangledRepresentationStartsWith(PEEK())) { - parseState()->addSubstitution(this); + parseState()->addSubstitution(parseState()->stackTop()); PARSE_RULE_AND_ADD_RESULT_AS_CHILD(TemplateArgsNode); } } else { @@ -2018,6 +2225,16 @@ void NameNode::parse() } +TemplateArgNode::TemplateArgNode(GlobalParseState *parseState) + : ParseTreeNode(parseState), m_isTemplateArgumentPack(false) +{ +} + +TemplateArgNode::TemplateArgNode(const TemplateArgNode &other) + : ParseTreeNode(other), m_isTemplateArgumentPack(other.m_isTemplateArgumentPack) +{ +} + bool TemplateArgNode::mangledRepresentationStartsWith(char c) { return TypeNode::mangledRepresentationStartsWith(c) @@ -2033,8 +2250,6 @@ bool TemplateArgNode::mangledRepresentationStartsWith(char c) */ void TemplateArgNode::parse() { - m_isTemplateArgumentPack = false; - const char next = PEEK(); if (TypeNode::mangledRepresentationStartsWith(next)) { PARSE_RULE_AND_ADD_RESULT_AS_CHILD(TypeNode); @@ -2056,7 +2271,12 @@ void TemplateArgNode::parse() throw ParseException(QString::fromLatin1("Invalid template-arg")); } - parseState()->addTemplateParam(this); + parseState()->addTemplateParam(parseState()->stackTop()); +} + +QByteArray TemplateArgNode::description() const +{ + return "TemplateArg[isPack:" + bool2String(m_isTemplateArgumentPack) + ']'; } QByteArray TemplateArgNode::toByteArray() const @@ -2071,112 +2291,28 @@ QByteArray TemplateArgNode::toByteArray() const } -bool Prefix2Node::mangledRepresentationStartsWith(char c) -{ - return UnqualifiedNameNode::mangledRepresentationStartsWith(c) - || SourceNameNode::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 childCount() > 0 && 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; -} - -/* - * <prefix-2> ::= <unqualified-name> [<template-args>] <prefix-2> - * ::= <data-member-prefix> <prefix2> - * ::= # empty - * - * <data-member-prefix> has overlap in its rhs with <unqualified-name>, so we cannot make it - * a node of its own. Instead, we just check whether a source name is followed by 'M' and - * remember that. - */ -void Prefix2Node::parse() -{ - ParseTreeNode * const prefixNode - = parseState()->stackElementAt(parseState()->stackElementCount() - 2); - - bool firstRun = true; - while (UnqualifiedNameNode::mangledRepresentationStartsWith(PEEK())) { - if (!firstRun) - parseState()->addSubstitution(prefixNode->toByteArray() + toByteArray()); - firstRun = false; - PARSE_RULE_AND_ADD_RESULT_AS_CHILD(UnqualifiedNameNode); - const bool isDataMember = dynamic_cast<SourceNameNode *>( - CHILD_AT(MY_CHILD_AT(childCount() - 1), 0)) && PEEK() == 'M'; - if (isDataMember) { - // TODO: Being a data member is apparently relevant for initializers, but what does - // this mean for the demangled string? - ADVANCE(); - continue; - } - if (TemplateArgsNode::mangledRepresentationStartsWith(PEEK())) { - parseState()->addSubstitution(prefixNode->toByteArray() + toByteArray()); - PARSE_RULE_AND_ADD_RESULT_AS_CHILD(TemplateArgsNode); - } - } -} - - bool PrefixNode::mangledRepresentationStartsWith(char c) { return TemplateParamNode::mangledRepresentationStartsWith(c) || SubstitutionNode::mangledRepresentationStartsWith(c) - || Prefix2Node::mangledRepresentationStartsWith(c) + || UnqualifiedNameNode::mangledRepresentationStartsWith(c) + || SourceNameNode::mangledRepresentationStartsWith(c) || DeclTypeNode::mangledRepresentationStartsWith(c); } - -QByteArray PrefixNode::toByteArray() const -{ - if (childCount() == 0) // Can only happen when inserting a substitution from Prefix2Node::parse(). - return QByteArray(); - 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(); + return childCount() > 0 && MY_CHILD_AT(childCount() - 1).dynamicCast<TemplateArgsNode>(); } bool PrefixNode::isConstructorOrDestructorOrConversionOperator() const { - const Prefix2Node * const childNode - = DEMANGLER_CAST(Prefix2Node, MY_CHILD_AT(childCount() - 1)); - return childNode->isConstructorOrDestructorOrConversionOperator(); + for (int i = childCount() - 1; i >= 0; --i) { + const UnqualifiedNameNode::Ptr n = MY_CHILD_AT(i).dynamicCast<UnqualifiedNameNode>(); + if (n) + return n->isConstructorOrDestructorOrConversionOperator(); + } + return false; } /* @@ -2198,40 +2334,77 @@ bool PrefixNode::isConstructorOrDestructorOrConversionOperator() const * ::= <substitution> [<template-args>] <prefix-2> * ::= <decltype> [<template-args>] <prefix-2> * ::= <prefix-2> + * <prefix-2> ::= <unqualified-name> [<template-args>] <prefix-2> + * ::= <data-member-prefix> <prefix2> + * ::= # empty + * <data-member-prefix> has overlap in its rhs with <unqualified-name>, so we cannot make it + * a node of its own. Instead, we just check whether a source name is followed by 'M' and + * remember that. */ void PrefixNode::parse() { const char next = PEEK(); + bool canAddSubstitution = false; if (TemplateParamNode::mangledRepresentationStartsWith(next)) { PARSE_RULE_AND_ADD_RESULT_AS_CHILD(TemplateParamNode); if (TemplateArgsNode::mangledRepresentationStartsWith(PEEK())) { - parseState()->addSubstitution(this); + parseState()->addSubstitution(parseState()->stackTop()); PARSE_RULE_AND_ADD_RESULT_AS_CHILD(TemplateArgsNode); } - if (Prefix2Node::mangledRepresentationStartsWith(PEEK())) - parseState()->addSubstitution(this); - PARSE_RULE_AND_ADD_RESULT_AS_CHILD(Prefix2Node); + canAddSubstitution = true; } else if (SubstitutionNode::mangledRepresentationStartsWith(next)) { PARSE_RULE_AND_ADD_RESULT_AS_CHILD(SubstitutionNode); if (TemplateArgsNode::mangledRepresentationStartsWith(PEEK())) { PARSE_RULE_AND_ADD_RESULT_AS_CHILD(TemplateArgsNode); - if (Prefix2Node::mangledRepresentationStartsWith(PEEK())) - parseState()->addSubstitution(this); + canAddSubstitution = true; } - PARSE_RULE_AND_ADD_RESULT_AS_CHILD(Prefix2Node); } else if (DeclTypeNode::mangledRepresentationStartsWith(next)) { PARSE_RULE_AND_ADD_RESULT_AS_CHILD(SubstitutionNode); if (TemplateArgsNode::mangledRepresentationStartsWith(PEEK())) { PARSE_RULE_AND_ADD_RESULT_AS_CHILD(TemplateArgsNode); - if (Prefix2Node::mangledRepresentationStartsWith(PEEK())) - parseState()->addSubstitution(this); + canAddSubstitution = true; + } + } + + while (UnqualifiedNameNode::mangledRepresentationStartsWith(PEEK())) { + if (canAddSubstitution) + parseState()->addSubstitution(parseState()->stackTop()); + else + canAddSubstitution = true; + PARSE_RULE_AND_ADD_RESULT_AS_CHILD(UnqualifiedNameNode); + const bool isDataMember = CHILD_AT(MY_CHILD_AT(childCount() - 1), 0) + .dynamicCast<SourceNameNode>() && PEEK() == 'M'; + if (isDataMember) { + // TODO: Being a data member is apparently relevant for initializers, but what does + // this mean for the demangled string? + ADVANCE(); + continue; + } + if (TemplateArgsNode::mangledRepresentationStartsWith(PEEK())) { + parseState()->addSubstitution(parseState()->stackTop()); + PARSE_RULE_AND_ADD_RESULT_AS_CHILD(TemplateArgsNode); } - PARSE_RULE_AND_ADD_RESULT_AS_CHILD(Prefix2Node); - } else { - PARSE_RULE_AND_ADD_RESULT_AS_CHILD(Prefix2Node); } } +QByteArray PrefixNode::toByteArray() const +{ + if (childCount() == 0) + return QByteArray(); + QByteArray repr = CHILD_TO_BYTEARRAY(0); + for (int i = 1; i < childCount(); ++i) { + if (!MY_CHILD_AT(i).dynamicCast<TemplateArgsNode>()) + repr += "::"; + repr += CHILD_TO_BYTEARRAY(i); + } + return repr; +} + + +TypeNode::TypeNode(const TypeNode &other) + : ParseTreeNode(other), m_type(other.type()) +{ +} bool TypeNode::mangledRepresentationStartsWith(char c) { @@ -2281,7 +2454,6 @@ bool TypeNode::mangledRepresentationStartsWith(char c) */ void TypeNode::parse() { - m_type = OtherType; QByteArray str = parseState()->readAhead(2); if (str == "Dp") { m_type = PackExpansionType; @@ -2296,16 +2468,16 @@ void TypeNode::parse() PARSE_RULE_AND_ADD_RESULT_AS_CHILD(BuiltinTypeNode); } else if (FunctionTypeNode::mangledRepresentationStartsWith(next)) { PARSE_RULE_AND_ADD_RESULT_AS_CHILD(FunctionTypeNode); - parseState()->addSubstitution(this); + parseState()->addSubstitution(parseState()->stackTop()); } else if (ClassEnumTypeRule::mangledRepresentationStartsWith(next)) { - ClassEnumTypeRule::parse(parseState(), this); - parseState()->addSubstitution(this); + ClassEnumTypeRule::parse(parseState()); + parseState()->addSubstitution(parseState()->stackTop()); } else if (ArrayTypeNode::mangledRepresentationStartsWith(next)) { PARSE_RULE_AND_ADD_RESULT_AS_CHILD(ArrayTypeNode); - parseState()->addSubstitution(this); + parseState()->addSubstitution(parseState()->stackTop()); } else if (PointerToMemberTypeNode::mangledRepresentationStartsWith(next)) { PARSE_RULE_AND_ADD_RESULT_AS_CHILD(PointerToMemberTypeNode); - parseState()->addSubstitution(this); + parseState()->addSubstitution(parseState()->stackTop()); } else if (TemplateParamNode::mangledRepresentationStartsWith(next)) { PARSE_RULE_AND_ADD_RESULT_AS_CHILD(TemplateParamNode); // The type is now a substitution candidate, but the child node may contain a forward @@ -2319,7 +2491,7 @@ void TypeNode::parse() } // Resolve forward reference, if necessary. - TemplateParamNode * const templateParamNode + const TemplateParamNode::Ptr templateParamNode = DEMANGLER_CAST(TemplateParamNode, MY_CHILD_AT(0)); if (templateParamNode->childCount() == 0) { if (templateParamNode->index() >= parseState()->templateParamCount()) { @@ -2333,44 +2505,44 @@ void TypeNode::parse() // Delayed substitutions from above. parseState()->addSubstitution(templateParamNode); if (childCount() > 1) - parseState()->addSubstitution(this); + parseState()->addSubstitution(parseState()->stackTop()); } else if (SubstitutionNode::mangledRepresentationStartsWith(next)) { + m_type = SubstitutionType; PARSE_RULE_AND_ADD_RESULT_AS_CHILD(SubstitutionNode); if (TemplateArgsNode::mangledRepresentationStartsWith(PEEK())) { PARSE_RULE_AND_ADD_RESULT_AS_CHILD(TemplateArgsNode); - parseState()->addSubstitution(this); + parseState()->addSubstitution(parseState()->stackTop()); } } else if (CvQualifiersNode::mangledRepresentationStartsWith(next)) { m_type = QualifiedType; PARSE_RULE_AND_ADD_RESULT_AS_CHILD(CvQualifiersNode); PARSE_RULE_AND_ADD_RESULT_AS_CHILD(TypeNode); - const CvQualifiersNode * const cvNode - = DEMANGLER_CAST(CvQualifiersNode, MY_CHILD_AT(0)); + const CvQualifiersNode::Ptr cvNode = DEMANGLER_CAST(CvQualifiersNode, MY_CHILD_AT(0)); if (cvNode->hasQualifiers()) - parseState()->addSubstitution(this); + parseState()->addSubstitution(parseState()->stackTop()); } else if (next == 'P') { m_type = PointerType; ADVANCE(); PARSE_RULE_AND_ADD_RESULT_AS_CHILD(TypeNode); - parseState()->addSubstitution(this); + parseState()->addSubstitution(parseState()->stackTop()); } else if (next == 'R') { m_type = ReferenceType; ADVANCE(); PARSE_RULE_AND_ADD_RESULT_AS_CHILD(TypeNode); - parseState()->addSubstitution(this); + parseState()->addSubstitution(parseState()->stackTop()); } else if (next == 'O') { m_type = RValueType; ADVANCE(); PARSE_RULE_AND_ADD_RESULT_AS_CHILD(TypeNode); - parseState()->addSubstitution(this); + parseState()->addSubstitution(parseState()->stackTop()); } else if (next == 'C') { ADVANCE(); PARSE_RULE_AND_ADD_RESULT_AS_CHILD(TypeNode); - parseState()->addSubstitution(this); + parseState()->addSubstitution(parseState()->stackTop()); } else if (next == 'G') { ADVANCE(); PARSE_RULE_AND_ADD_RESULT_AS_CHILD(TypeNode); - parseState()->addSubstitution(this); + parseState()->addSubstitution(parseState()->stackTop()); } else if (next == 'U') { m_type = VendorType; ADVANCE(); @@ -2382,6 +2554,11 @@ void TypeNode::parse() } } +QByteArray TypeNode::description() const +{ + return "Type[type:" + QByteArray::number(m_type) + ']'; +} + QByteArray TypeNode::toByteArray() const { // A pure top-down approach is not possible to due to the weird function pointer syntax, @@ -2398,11 +2575,11 @@ QByteArray TypeNode::toByteArray() const Type currentType = currentNode->m_type; switch (currentType) { case QualifiedType: { - const CvQualifiersNode * const cvNode + const CvQualifiersNode::Ptr cvNode = DEMANGLER_CAST(CvQualifiersNode, CHILD_AT(currentNode, 0)); if (cvNode->hasQualifiers()) - qualPtrRefList << cvNode; - currentNode = DEMANGLER_CAST(TypeNode, CHILD_AT(currentNode, 1)); + qualPtrRefList << cvNode.data(); + currentNode = DEMANGLER_CAST(TypeNode, CHILD_AT(currentNode, 1)).data(); break; } case PointerType: case ReferenceType: case RValueType: @@ -2425,12 +2602,36 @@ QByteArray TypeNode::toByteArray() const } else { qualPtrRefList << currentNode; } - currentNode = DEMANGLER_CAST(TypeNode, CHILD_AT(currentNode, 0)); + currentNode = DEMANGLER_CAST(TypeNode, CHILD_AT(currentNode, 0)).data(); break; - default: + default: { + ParseTreeNode::Ptr childNode = CHILD_AT(currentNode, 0); + while (true) { + if (childCount() != 1) + break; + SubstitutionNode::Ptr substNode = childNode.dynamicCast<SubstitutionNode>(); + if (substNode && substNode->type() == SubstitutionNode::ActualSubstitutionType) { + childNode = CHILD_AT(childNode, 0); + } else if (childNode.dynamicCast<TemplateParamNode>()) { + childNode = CHILD_AT(childNode, 0); + if (childNode.dynamicCast<TemplateArgNode>()) + childNode = CHILD_AT(childNode, 0); + } else { + break; + } + } + if (childNode != CHILD_AT(currentNode, 0)) { + const TypeNode::Ptr nextCurrent = childNode.dynamicCast<TypeNode>(); + if (nextCurrent) { + currentNode = nextCurrent.data(); + continue; + } + } + leafType = true; break; } + } lastType = currentType; } @@ -2451,10 +2652,10 @@ QByteArray TypeNode::toByteArray() const QByteArray TypeNode::toByteArrayQualPointerRef(const TypeNode *typeNode, const QByteArray &qualPtrRef) const { - const FunctionTypeNode * const functionNode - = dynamic_cast<FunctionTypeNode *>(CHILD_AT(typeNode, 0)); + const FunctionTypeNode::Ptr functionNode + = CHILD_AT(typeNode, 0).dynamicCast<FunctionTypeNode>(); if (functionNode) { - const BareFunctionTypeNode * const bareFunctionNode + const BareFunctionTypeNode::Ptr bareFunctionNode = DEMANGLER_CAST(BareFunctionTypeNode, CHILD_AT(functionNode, 0)); QByteArray repr; if (functionNode->isExternC()) @@ -2464,13 +2665,13 @@ QByteArray TypeNode::toByteArrayQualPointerRef(const TypeNode *typeNode, return repr += '(' + qualPtrRef + ')' + bareFunctionNode->toByteArray(); } - const ArrayTypeNode * const arrayNode = dynamic_cast<ArrayTypeNode *>(CHILD_AT(typeNode, 0)); + const ArrayTypeNode::Ptr arrayNode = CHILD_AT(typeNode, 0).dynamicCast<ArrayTypeNode>(); if (arrayNode) { return CHILD_AT(arrayNode, 1)->toByteArray() + " (" + qualPtrRef + ")[" + CHILD_AT(arrayNode, 0)->toByteArray() + ']'; } - if (dynamic_cast<PointerToMemberTypeNode *>(CHILD_AT(typeNode, 0))) + if (CHILD_AT(typeNode, 0).dynamicCast<PointerToMemberTypeNode>()) return typeNode->toByteArray() + qualPtrRef; return typeNode->toByteArray() + ' ' + qualPtrRef; @@ -2512,6 +2713,11 @@ QByteArray TypeNode::qualPtrRefListToByteArray(const QList<const ParseTreeNode * } +FloatValueNode::FloatValueNode(const FloatValueNode &other) + : ParseTreeNode(other), m_value(other.m_value) +{ +} + bool FloatValueNode::mangledRepresentationStartsWith(char c) { return strchr("0123456789abcdef", c); @@ -2532,6 +2738,11 @@ void FloatValueNode::parse() } } +QByteArray FloatValueNode::description() const +{ + return "FloatValue[value:" + QByteArray::number(m_value) + ']'; +} + QByteArray FloatValueNode::toByteArray() const { return QByteArray::number(m_value); @@ -2604,7 +2815,7 @@ QByteArray ClosureTypeNameNode::toByteArray() const QByteArray repr = CHILD_TO_BYTEARRAY(0) + '#'; quint64 number; if (childCount() == 2) { - const NonNegativeNumberNode<10> * const numberNode + const typename NonNegativeNumberNode<10>::Ptr numberNode = DEMANGLER_CAST(NonNegativeNumberNode<10>, MY_CHILD_AT(1)); number = numberNode->number() + 2; } else { @@ -2642,8 +2853,8 @@ QByteArray UnnamedTypeNameNode::toByteArray() const if (childCount() == 0) { repr += "unnamed type#1"; } else { - const NonNegativeNumberNode<10> * const numberNode - = dynamic_cast<NonNegativeNumberNode<10> *>(MY_CHILD_AT(0)); + const typename NonNegativeNumberNode<10>::Ptr numberNode + = MY_CHILD_AT(0).dynamicCast<NonNegativeNumberNode<10> >(); if (numberNode) repr += "unnamed type#" + QByteArray::number(numberNode->number() + 2); else @@ -2691,9 +2902,10 @@ bool UnresolvedTypeRule::mangledRepresentationStartsWith(char c) * ::= <decltype> * ::= <substitution> */ -void UnresolvedTypeRule::parse(GlobalParseState *parseState, ParseTreeNode *parentNode) +void UnresolvedTypeRule::parse(GlobalParseState *parseState) { const char next = parseState->peek(); + const ParseTreeNode::Ptr parentNode = parseState->stackTop(); if (TemplateParamNode::mangledRepresentationStartsWith(next)) PARSE_RULE_AND_ADD_RESULT_AS_CHILD_TO_NODE(TemplateParamNode, parseState, parentNode); else if (DeclTypeNode::mangledRepresentationStartsWith(next)) @@ -2738,7 +2950,7 @@ void DestructorNameNode::parse() { const char next = PEEK(); if (UnresolvedTypeRule::mangledRepresentationStartsWith(next)) - UnresolvedTypeRule::parse(parseState(), this); + UnresolvedTypeRule::parse(parseState()); else if (SimpleIdNode::mangledRepresentationStartsWith(next)) PARSE_RULE_AND_ADD_RESULT_AS_CHILD(SimpleIdNode); else @@ -2757,12 +2969,22 @@ bool UnresolvedQualifierLevelRule::mangledRepresentationStartsWith(char c) } // <unresolved-qualifier-level> ::= <simple-id> - void UnresolvedQualifierLevelRule::parse(GlobalParseState *parseState, ParseTreeNode *parentNode) + void UnresolvedQualifierLevelRule::parse(GlobalParseState *parseState) { - PARSE_RULE_AND_ADD_RESULT_AS_CHILD_TO_NODE(SimpleIdNode, parseState, parentNode); + PARSE_RULE_AND_ADD_RESULT_AS_CHILD_TO_NODE(SimpleIdNode, parseState, parseState->stackTop()); } +BaseUnresolvedNameNode::BaseUnresolvedNameNode(GlobalParseState *parseState) + : ParseTreeNode(parseState), m_isOperator(false) +{ +} + +BaseUnresolvedNameNode::BaseUnresolvedNameNode(const BaseUnresolvedNameNode &other) + : ParseTreeNode(other), m_isOperator(other.m_isOperator) +{ +} + bool BaseUnresolvedNameNode::mangledRepresentationStartsWith(char c) { return SimpleIdNode::mangledRepresentationStartsWith(c) || c == 'o' || c == 'd'; @@ -2777,7 +2999,6 @@ bool BaseUnresolvedNameNode::mangledRepresentationStartsWith(char c) */ void BaseUnresolvedNameNode::parse() { - m_isOperator = false; if (SimpleIdNode::mangledRepresentationStartsWith(PEEK())) { PARSE_RULE_AND_ADD_RESULT_AS_CHILD(SimpleIdNode); } else if (parseState()->readAhead(2) == "on") { @@ -2794,6 +3015,11 @@ void BaseUnresolvedNameNode::parse() } } +QByteArray BaseUnresolvedNameNode::description() const +{ + return "BaseUnresolvedName[isOperator:" + bool2String(m_isOperator) + ']'; +} + QByteArray BaseUnresolvedNameNode::toByteArray() const { QByteArray repr; @@ -2832,6 +3058,11 @@ QByteArray InitializerNode::toByteArray() const } +UnresolvedNameNode::UnresolvedNameNode(const UnresolvedNameNode &other) + : ParseTreeNode(other), m_globalNamespace(other.m_globalNamespace) +{ +} + bool UnresolvedNameNode::mangledRepresentationStartsWith(char c) { return BaseUnresolvedNameNode::mangledRepresentationStartsWith(c) || c == 'g' || c == 's'; @@ -2857,9 +3088,9 @@ void UnresolvedNameNode::parse() parseState()->advance(2); if (PEEK() == 'N') { ADVANCE(); - UnresolvedTypeRule::parse(parseState(), this); + UnresolvedTypeRule::parse(parseState()); do - UnresolvedQualifierLevelRule::parse(parseState(), this); + UnresolvedQualifierLevelRule::parse(parseState()); while (UnresolvedQualifierLevelRule::mangledRepresentationStartsWith(PEEK())); if (ADVANCE() != 'E') throw ParseException("Invalid unresolev-name"); @@ -2867,13 +3098,13 @@ void UnresolvedNameNode::parse() } else if (UnresolvedTypeRule::mangledRepresentationStartsWith(PEEK())) { if (m_globalNamespace) throw ParseException("Invalid unresolved-name"); - UnresolvedTypeRule::parse(parseState(), this); + UnresolvedTypeRule::parse(parseState()); PARSE_RULE_AND_ADD_RESULT_AS_CHILD(BaseUnresolvedNameNode); } else { if (!UnresolvedQualifierLevelRule::mangledRepresentationStartsWith(PEEK())) throw ParseException("Invalid unresolved-name"); while (UnresolvedQualifierLevelRule::mangledRepresentationStartsWith(PEEK())) - UnresolvedQualifierLevelRule::parse(parseState(), this); + UnresolvedQualifierLevelRule::parse(parseState()); if (ADVANCE() != 'E') throw ParseException("Invalid unresolved-name"); PARSE_RULE_AND_ADD_RESULT_AS_CHILD(BaseUnresolvedNameNode); @@ -2883,6 +3114,11 @@ void UnresolvedNameNode::parse() } } +QByteArray UnresolvedNameNode::description() const +{ + return "UnresolvedName[globalNamespace:" + bool2String(m_globalNamespace) + ']'; +} + QByteArray UnresolvedNameNode::toByteArray() const { QByteArray repr; @@ -2935,11 +3171,11 @@ void FunctionParamNode::parse() QByteArray FunctionParamNode::toByteArray() const { // We ignore L for now. - const NonNegativeNumberNode<10> * const numberNode - = dynamic_cast<NonNegativeNumberNode<10> *>(MY_CHILD_AT(childCount() - 1)); + const typename NonNegativeNumberNode<10>::Ptr numberNode + = MY_CHILD_AT(childCount() - 1).dynamicCast<NonNegativeNumberNode<10> >(); const int paramNumber = numberNode ? numberNode->number() + 2 : 1; - const int cvIndex = dynamic_cast<CvQualifiersNode *>(MY_CHILD_AT(0)) ? 0 : 1; - const CvQualifiersNode * const cvNode = DEMANGLER_CAST(CvQualifiersNode, MY_CHILD_AT(cvIndex)); + const int cvIndex = MY_CHILD_AT(0).dynamicCast<CvQualifiersNode>() ? 0 : 1; + const CvQualifiersNode::Ptr cvNode = DEMANGLER_CAST(CvQualifiersNode, MY_CHILD_AT(cvIndex)); QByteArray repr = "{param#" + QByteArray::number(paramNumber); if (cvNode->hasQualifiers()) repr.append(' ').append(cvNode->toByteArray()); diff --git a/src/plugins/debugger/namedemangler/parsetreenodes.h b/src/plugins/debugger/namedemangler/parsetreenodes.h index c8f337cf51..a9567a2ca9 100644 --- a/src/plugins/debugger/namedemangler/parsetreenodes.h +++ b/src/plugins/debugger/namedemangler/parsetreenodes.h @@ -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 |