diff --git a/share/qtcreator/gdbmacros/gdbmacros.cpp b/share/qtcreator/gdbmacros/gdbmacros.cpp index b3a80a5d24df9ccfade444c0dbb2ebb6d06af0f8..c1227b79c0acf03e8ed65243e61a5b11a506850f 100644 --- a/share/qtcreator/gdbmacros/gdbmacros.cpp +++ b/share/qtcreator/gdbmacros/gdbmacros.cpp @@ -37,6 +37,7 @@ #include <QtCore/QHash> #include <QtCore/QLinkedList> #include <QtCore/QList> +#include <QtCore/QQueue> #include <QtCore/QLocale> #include <QtCore/QMap> #include <QtCore/QMetaEnum> @@ -3572,15 +3573,15 @@ template <class Key, class Value> { QMapNode<Key, Value> *mn = 0; const int valueOffset = (char *)&(mn->value) - (char*)mn; - d.put("(size_t)&(('"NS"QMapNode<"); + d.put("[\"(size_t)&(('"NS"QMapNode<"); d.put(keyType); d.put(','); d.put(valueType); if (valueType[qstrlen(valueType) - 1] == '>') d.put(' '); - d.put(">'*)0)->value=\""); + d.put(">'*)0)->value\",\""); d.put(valueOffset); - d.put('"'); + d.put("\"]"); return d; } @@ -3595,20 +3596,86 @@ template <class Key, class Value> { std::pair<Key, Value> *p = 0; const int valueOffset = (char *)&(p->second) - (char*)p; - d.put("(size_t)&(('std::pair<"); + d.put("[\"(size_t)&(('std::pair<"); d.put(keyType); d.put(" const ,"); d.put(valueType); if (valueType[qstrlen(valueType) - 1] == '>') d.put(' '); - d.put(">'*)0)->second=\""); + d.put(">'*)0)->second\",\""); d.put(valueOffset); - d.put('"'); + d.put("\"]"); return d; } #endif // Q_CC_MSVC +// Dump out sizes for CDB +static inline void dumpSizes(QDumper &d) +{ + // Sort by sizes + typedef QMultiMap<size_t, const char *> SizeMap; + SizeMap sizeMap; + + sizeMap.insert(sizeof(int), "int"); + sizeMap.insert(sizeof(char*), "char*"); + sizeMap.insert(sizeof(QString), NS"QString"); + sizeMap.insert(sizeof(QStringList), NS"QStringList"); +#ifndef QT_BOOTSTRAPPED + sizeMap.insert(sizeof(QObject), NS"QObject"); + sizeMap.insert(sizeof(QList<int>), NS"QList<int>"); + sizeMap.insert(sizeof(QLinkedList<int>), NS"QLinkedList<int>"); + sizeMap.insert(sizeof(QVector<int>), NS"QVector<int>"); + sizeMap.insert(sizeof(QQueue<int>), NS"QQueue<int>"); +#endif +#if USE_QT_GUI + sizeMap.insert(sizeof(QWidget), NS"QWidget"); +#endif +#ifdef Q_OS_WIN + sizeMap.insert(sizeof(std::string), "string"); + sizeMap.insert(sizeof(std::wstring), "wstring"); +#endif + sizeMap.insert(sizeof(std::string), "std::string"); + sizeMap.insert(sizeof(std::wstring), "std::wstring"); + sizeMap.insert(sizeof(std::allocator<int>), "std::allocator"); + sizeMap.insert(sizeof(std::char_traits<char>), "std::char_traits<char>"); + sizeMap.insert(sizeof(std::char_traits<unsigned short>), "std::char_traits<unsigned short>"); +#ifndef QT_BOOTSTRAPPED +#if QT_VERSION >= 0x040500 + sizeMap.insert(sizeof(QSharedPointer<int>), NS"QSharedPointer"); + sizeMap.insert(sizeof(QSharedDataPointer<QSharedData>), NS"QSharedDataPointer"); + sizeMap.insert(sizeof(QWeakPointer<int>), NS"QWeakPointer"); +#endif +#endif // QT_BOOTSTRAPPED + sizeMap.insert(sizeof(QPointer<QObject>), "QPointer"); + // Common map node types + sizeMap.insert(sizeof(QMapNode<int,int >), NS"QMapNode<int,int>"); + sizeMap.insert(sizeof(QMapNode<int, QString>), NS"QMapNode<int,"NS"QString>"); + sizeMap.insert(sizeof(QMapNode<int, QVariant>), NS"QMapNode<int,"NS"QVariant>"); + sizeMap.insert(sizeof(QMapNode<QString, int>), NS"QMapNode<"NS"QString,int>"); + sizeMap.insert(sizeof(QMapNode<QString, QString>), NS"QMapNode<"NS"QString,"NS"QString>"); + sizeMap.insert(sizeof(QMapNode<QString, QVariant>), NS"QMapNode<"NS"QString,"NS"QVariant>"); + // Dump as lists of types preceded by size + size_t lastSize = 0; + d.put("sizes=["); + const SizeMap::const_iterator cend = sizeMap.constEnd(); + for (SizeMap::const_iterator it = sizeMap.constBegin(); it != cend; ++it) { + // new size list + if (it.key() != lastSize) { + if (lastSize) + d.put("],"); + d.put("[\""); + d.put(it.key()); + lastSize = it.key(); + d.put('"'); + } + d.put(",\""); + d.put(it.value()); + d.put('"'); + } + d.put("]]"); +} + extern "C" Q_DECL_EXPORT void *qDumpObjectData440( int protocolVersion, @@ -3702,45 +3769,10 @@ void *qDumpObjectData440( d.put(",namespace=\""NS"\","); d.put("dumperversion=\"1.3\","); // Dump out size information - d.put("sizes={"); - d.put("int=\"").put(sizeof(int)).put("\",") - .put("char*=\"").put(sizeof(char*)).put("\",") - .put(""NS"QString=\"").put(sizeof(QString)).put("\",") - .put(""NS"QStringList=\"").put(sizeof(QStringList)).put("\",") -#ifndef QT_BOOTSTRAPPED - .put(""NS"QObject=\"").put(sizeof(QObject)).put("\",") -#endif -#if USE_QT_GUI - .put(""NS"QWidget=\"").put(sizeof(QWidget)).put("\",") -#endif -#ifdef Q_OS_WIN - .put("string=\"").put(sizeof(std::string)).put("\",") - .put("wstring=\"").put(sizeof(std::wstring)).put("\",") -#endif - .put("std::string=\"").put(sizeof(std::string)).put("\",") - .put("std::wstring=\"").put(sizeof(std::wstring)).put("\",") - .put("std::allocator=\"").put(sizeof(std::allocator<int>)).put("\",") - .put("std::char_traits<char>=\"").put(sizeof(std::char_traits<char>)).put("\",") - .put("std::char_traits<unsigned short>=\"").put(sizeof(std::char_traits<unsigned short>)).put("\",") -#ifndef QT_BOOTSTRAPPED -#if QT_VERSION >= 0x040500 - .put(NS"QSharedPointer=\"").put(sizeof(QSharedPointer<int>)).put("\",") - .put(NS"QSharedDataPointer=\"").put(sizeof(QSharedDataPointer<QSharedData>)).put("\",") - .put(NS"QWeakPointer=\"").put(sizeof(QWeakPointer<int>)).put("\",") -#endif -#endif // QT_BOOTSTRAPPED - .put("QPointer=\"").put(sizeof(QPointer<QObject>)).put("\",") - // Common map node types - .put(NS"QMapNode<int,int>=\"").put(sizeof(QMapNode<int,int >)).put("\",") - .put(NS"QMapNode<int,"NS"QString>=\"").put(sizeof(QMapNode<int, QString>)).put("\",") - .put(NS"QMapNode<int,"NS"QVariant>=\"").put(sizeof(QMapNode<int, QVariant>)).put("\",") - .put(NS"QMapNode<"NS"QString,int>=\"").put(sizeof(QMapNode<QString, int>)).put("\",") - .put(NS"QMapNode<"NS"QString,"NS"QString>=\"").put(sizeof(QMapNode<QString, QString>)).put("\",") - .put(NS"QMapNode<"NS"QString,"NS"QVariant>=\"").put(sizeof(QMapNode<QString, QVariant>)) - .put("\"}"); + dumpSizes(d); // Write out common expression values for CDB #ifdef Q_CC_MSVC - d.put(",expressions={"); + d.put(",expressions=["); putQMapNodeOffsetExpression<int,int>("int", "int", d).put(','); putQMapNodeOffsetExpression<int,QString>("int", NS"QString", d).put(','); putQMapNodeOffsetExpression<int,QVariant>("int", NS"QVariant", d).put(','); @@ -3754,11 +3786,11 @@ void *qDumpObjectData440( putStdPairValueOffsetExpression<QString,int>(NS"QString", "int", d).put(','); putStdPairValueOffsetExpression<std::string,std::string>(stdStringTypeC, stdStringTypeC, d).put(','); putStdPairValueOffsetExpression<int,std::string>("int", stdStringTypeC, d).put(','); - putStdPairValueOffsetExpression<std::string,int>(stdStringTypeC, "int", d.put(',')); + putStdPairValueOffsetExpression<std::string,int>(stdStringTypeC, "int", d).put(','); putStdPairValueOffsetExpression<std::wstring,std::wstring>(stdWideStringTypeUShortC, stdWideStringTypeUShortC, d).put(','); putStdPairValueOffsetExpression<int,std::wstring>("int", stdWideStringTypeUShortC, d).put(','); putStdPairValueOffsetExpression<std::wstring,int>(stdWideStringTypeUShortC, "int", d); - d.put('}'); + d.put(']'); #endif // Q_CC_MSVC d.disarm(); } diff --git a/share/qtcreator/gdbmacros/gdbmacros_p.h b/share/qtcreator/gdbmacros/gdbmacros_p.h index 0aed16d3781102faf9e9da5ab3fe4ebf664681d6..7914e04aa448639e344dfd85c3f95e0e830ae69a 100644 --- a/share/qtcreator/gdbmacros/gdbmacros_p.h +++ b/share/qtcreator/gdbmacros/gdbmacros_p.h @@ -152,8 +152,6 @@ public: QList<QObject *> pendingChildInsertedEvents; QList<QPointer<QObject> > eventFilters; void *currentChildBeingDeleted; - void *declarativeData; - void *objectGuards; QAtomicPointer<void> sharedRefcount; int *deleteWatch; #endif diff --git a/share/qtcreator/gdbmacros/test/main.cpp b/share/qtcreator/gdbmacros/test/main.cpp index 39956dcb0fb52f946f2c414a479e78171a76e37d..b6be579ab383600ca0a736321568c5e75008035d 100644 --- a/share/qtcreator/gdbmacros/test/main.cpp +++ b/share/qtcreator/gdbmacros/test/main.cpp @@ -28,10 +28,12 @@ **************************************************************************/ #include <QtCore/QStringList> +#include <QtCore/QLinkedList> #include <QtCore/QVector> #include <QtCore/QSharedPointer> #include <QtCore/QTimer> #include <QtCore/QMap> +#include <QtCore/QSet> #include <QtCore/QVariant> #include <QtGui/QAction> @@ -138,6 +140,16 @@ static int dumpQIntList() return 0; } +static int dumpQIntLinkedList() +{ + QLinkedList<int> test = QLinkedList<int>() << 1 << 2; + prepareInBuffer("QLinkedList", "local.qintlinkedlist", "local.qlinkedintlist", "int"); + qDumpObjectData440(2, 42, testAddress(&test), 1, sizeof(int), 0, 0, 0); + fputs(qDumpOutBuffer, stdout); + fputc('\n', stdout); + return 0; +} + static int dumpQIntVector() { QVector<int> test = QVector<int>() << 42 << 43; @@ -148,6 +160,16 @@ static int dumpQIntVector() return 0; } +static int dumpQQStringVector() +{ + QVector<QString> test = QVector<QString>() << "42s" << "43s"; + prepareInBuffer("QVector", "local.qstringvector", "local.qstringvector", "QString"); + qDumpObjectData440(2, 42, testAddress(&test), 1, sizeof(QString), 0, 0, 0); + fputs(qDumpOutBuffer, stdout); + fputc('\n', stdout); + return 0; +} + static int dumpQMapIntInt() { QMap<int,int> test; @@ -176,6 +198,33 @@ static int dumpQMapIntString() return 0; } +static int dumpQSetInt() +{ + QSet<int> test; + test.insert(42); + test.insert(43); + prepareInBuffer("QSet", "local.qsetint", "local.qsetint", "int"); + qDumpObjectData440(2, 42, testAddress(&test), 1, sizeof(int), 0, 0, 0); + fputs(qDumpOutBuffer, stdout); + fputc('\n', stdout); + return 0; +} + + +static int dumpQMapQStringString() +{ + QMap<QString,QString> test; + QMapNode<QString,QString> mapNode; + const int valueOffset = (char*)&(mapNode.value) - (char*)&mapNode; + test.insert(QLatin1String("42s"), QLatin1String("fortytwo")); + test.insert(QLatin1String("423"), QLatin1String("fortytree")); + prepareInBuffer("QMap", "local.qmapqstringqstring", "local.qmapqstringqstring", "QString@QString"); + qDumpObjectData440(2, 42, testAddress(&test), 1, sizeof(QString), sizeof(QString), sizeof(mapNode), valueOffset); + fputs(qDumpOutBuffer, stdout); + fputc('\n', stdout); + return 0; +} + static int dumpQVariant() { QVariant test(QLatin1String("item")); @@ -417,10 +466,14 @@ static TypeDumpFunctionMap registerTypes() rc.insert("QSharedPointer<QString>", dumpQSharedPointerQString); rc.insert("QStringList", dumpQStringList); rc.insert("QList<int>", dumpQIntList); + rc.insert("QLinkedList<int>", dumpQIntLinkedList); rc.insert("QList<std::string>", dumpStdStringQList); rc.insert("QVector<int>", dumpQIntVector); + rc.insert("QVector<QString>", dumpQQStringVector); rc.insert("QMap<int,QString>", dumpQMapIntString); + rc.insert("QMap<QString,QString>", dumpQMapQStringString); rc.insert("QMap<int,int>", dumpQMapIntInt); + rc.insert("QSet<int>", dumpQSetInt); rc.insert("string", dumpStdString); rc.insert("wstring", dumpStdWString); rc.insert("list<int>", dumpStdIntList); diff --git a/src/libs/cplusplus/BackwardsScanner.cpp b/src/libs/cplusplus/BackwardsScanner.cpp index b0b71ffecdf98e7234c93be90e2e245bd387ac9e..da12f3e599a2b6f039a6fdcc1479a9900d71045c 100644 --- a/src/libs/cplusplus/BackwardsScanner.cpp +++ b/src/libs/cplusplus/BackwardsScanner.cpp @@ -38,6 +38,7 @@ BackwardsScanner::BackwardsScanner(const QTextCursor &cursor, const QString &suf , _block(cursor.block()) , _maxBlockCount(maxBlockCount) { + _tokenize.setQtMocRunEnabled(true); _tokenize.setSkipComments(true); _text = _block.text().left(cursor.position() - cursor.block().position()); @@ -52,13 +53,10 @@ BackwardsScanner::BackwardsScanner(const QTextCursor &cursor, const QString &suf int BackwardsScanner::state() const { return _tokenize.state(); } -const QList<SimpleToken> &BackwardsScanner::tokens() const -{ return _tokens; } - -const SimpleToken &BackwardsScanner::LA(int index) const +SimpleToken BackwardsScanner::LA(int index) const { return const_cast<BackwardsScanner *>(this)->fetchToken(_startToken - index); } -const SimpleToken &BackwardsScanner::operator[](int index) const +SimpleToken BackwardsScanner::operator[](int index) const { return const_cast<BackwardsScanner *>(this)->fetchToken(index); } const SimpleToken &BackwardsScanner::fetchToken(int i) @@ -72,16 +70,15 @@ const SimpleToken &BackwardsScanner::fetchToken(int i) } else { ++_blocksTokenized; - QString blockText = _block.text(); + const QString blockText = _block.text(); _text.prepend(blockText); + QList<SimpleToken> adaptedTokens; for (int i = 0; i < _tokens.size(); ++i) { - const SimpleToken &t = _tokens.at(i); - const int position = t.position() + blockText.length(); - adaptedTokens.append(SimpleToken(t.kind(), - position, - t.length(), - _text.midRef(position, t.length()))); + SimpleToken t = _tokens.at(i); + t.setPosition(t.position() + blockText.length()); + t.setText(_text.midRef(t.position(), t.length())); + adaptedTokens.append(t); } _tokens = _tokenize(blockText, previousBlockState(_block)); @@ -102,18 +99,22 @@ int BackwardsScanner::startPosition() const QString BackwardsScanner::text() const { return _text; } -QString BackwardsScanner::text(int begin, int end) const +QString BackwardsScanner::mid(int index) const +{ + const SimpleToken &firstToken = _tokens.at(index + _offset); + return _text.mid(firstToken.begin()); +} + +QString BackwardsScanner::text(int index) const { - const SimpleToken &firstToken = _tokens.at(begin + _offset); - const SimpleToken &lastToken = _tokens.at(end + _offset - 1); - return _text.mid(firstToken.begin(), lastToken.end() - firstToken.begin()); + const SimpleToken &firstToken = _tokens.at(index + _offset); + return _text.mid(firstToken.begin(), firstToken.length()); } -QStringRef BackwardsScanner::textRef(int begin, int end) const +QStringRef BackwardsScanner::textRef(int index) const { - const SimpleToken &firstToken = _tokens.at(begin + _offset); - const SimpleToken &lastToken = _tokens.at(end + _offset - 1); - return _text.midRef(firstToken.begin(), lastToken.end() - firstToken.begin()); + const SimpleToken &firstToken = _tokens.at(index + _offset); + return _text.midRef(firstToken.begin(), firstToken.length()); } int BackwardsScanner::previousBlockState(const QTextBlock &block) const @@ -156,6 +157,17 @@ int BackwardsScanner::startOfMatchingBrace(int index) const --count; --i; } while (count != 0 && tk[i].isNot(T_EOF_SYMBOL)); + } else if (tk[index - 1].is(T_RBRACE)) { + int i = index - 1; + int count = 0; + do { + if (tk[i].is(T_LBRACE)) { + if (! ++count) + return i; + } else if (tk[i].is(T_RBRACE)) + --count; + --i; + } while (count != 0 && tk[i].isNot(T_EOF_SYMBOL)); } else if (tk[index - 1].is(T_GREATER)) { int i = index - 1; int count = 0; @@ -167,7 +179,71 @@ int BackwardsScanner::startOfMatchingBrace(int index) const --count; --i; } while (count != 0 && tk[i].isNot(T_EOF_SYMBOL)); + } else { + Q_ASSERT(0); + } + + return index; +} + +int BackwardsScanner::startOfLine(int index) const +{ + const BackwardsScanner tk(*this); + + forever { + const SimpleToken &tok = tk[index - 1]; + + if (tok.is(T_EOF_SYMBOL)) + break; + else if (tok.followsNewline()) + return index - 1; + + --index; } return index; } + +int BackwardsScanner::startOfBlock(int index) const +{ + const BackwardsScanner tk(*this); + + const int start = index; + + forever { + SimpleToken token = tk[index - 1]; + + if (token.is(T_EOF_SYMBOL)) { + break; + + } else if (token.is(T_GREATER)) { + const int matchingBrace = startOfMatchingBrace(index); + + if (matchingBrace != index && tk[matchingBrace - 1].is(T_TEMPLATE)) + index = matchingBrace; + + } else if (token.is(T_RPAREN) || token.is(T_RBRACKET) || token.is(T_RBRACE)) { + const int matchingBrace = startOfMatchingBrace(index); + + if (matchingBrace != index) + index = matchingBrace; + + } else if (token.is(T_LPAREN) || token.is(T_LBRACKET)) { + break; // unmatched brace + + } else if (token.is(T_LBRACE)) { + return index - 1; + + } + + --index; + } + + return start; +} + +int BackwardsScanner::indentation(int index) const +{ + SimpleToken newline = operator[](startOfLine(index + 1)); + return newline.position(); +} diff --git a/src/libs/cplusplus/BackwardsScanner.h b/src/libs/cplusplus/BackwardsScanner.h index 68d1f047878ff5440b0421d964e45665f613555b..b2e7414951e12d62d9d32d3dd5d0b08c2d0e1fae 100644 --- a/src/libs/cplusplus/BackwardsScanner.h +++ b/src/libs/cplusplus/BackwardsScanner.h @@ -51,21 +51,26 @@ public: int startPosition() const; QString text() const; - QString text(int begin, int end) const; - QStringRef textRef(int begin, int end) const; + QString mid(int index) const; + QString text(int index) const; + QStringRef textRef(int index) const; // 1-based - const SimpleToken &LA(int index) const; + SimpleToken LA(int index) const; // n-la token is [startToken - n] - const SimpleToken &operator[](int index) const; // ### deprecate + SimpleToken operator[](int index) const; // ### deprecate + int indentation(int index) const; + + int startOfLine(int index) const; int startOfMatchingBrace(int index) const; + int startOfBlock(int index) const; + int previousBlockState(const QTextBlock &block) const; private: const SimpleToken &fetchToken(int i); - const QList<SimpleToken> &tokens() const; private: QList<SimpleToken> _tokens; diff --git a/src/libs/cplusplus/ExpressionUnderCursor.cpp b/src/libs/cplusplus/ExpressionUnderCursor.cpp index 106e3040b1bd8abe923f865103afad8beffccee5..8016f537bb2de71be26d4f2688005784700971e4 100644 --- a/src/libs/cplusplus/ExpressionUnderCursor.cpp +++ b/src/libs/cplusplus/ExpressionUnderCursor.cpp @@ -150,7 +150,7 @@ QString ExpressionUnderCursor::operator()(const QTextCursor &cursor) if (i == initialSize) return QString(); - return scanner.text(i, initialSize); + return scanner.mid(i); } int ExpressionUnderCursor::startOfFunctionCall(const QTextCursor &cursor) const diff --git a/src/libs/cplusplus/MatchingText.cpp b/src/libs/cplusplus/MatchingText.cpp index 8813e890bee8dfd4cb9c7d35c10bb9d87f047917..bbbb06b83112c5f223423f5deb86b690f16fa04b 100644 --- a/src/libs/cplusplus/MatchingText.cpp +++ b/src/libs/cplusplus/MatchingText.cpp @@ -49,9 +49,9 @@ static bool shouldOverrideChar(const QChar &ch) } } -static bool isCompleteStringLiteral(const BackwardsScanner &tk, int index, int startToken) +static bool isCompleteStringLiteral(const BackwardsScanner &tk, int index) { - const QStringRef text = tk.textRef(index, startToken); + const QStringRef text = tk.textRef(index); if (text.length() < 2) return false; @@ -62,9 +62,9 @@ static bool isCompleteStringLiteral(const BackwardsScanner &tk, int index, int s return false; } -static bool isCompleteCharLiteral(const BackwardsScanner &tk, int index, int startToken) +static bool isCompleteCharLiteral(const BackwardsScanner &tk, int index) { - const QStringRef text = tk.textRef(index, startToken); + const QStringRef text = tk.textRef(index); if (text.length() < 2) return false; @@ -75,7 +75,16 @@ static bool isCompleteCharLiteral(const BackwardsScanner &tk, int index, int sta return false; } -static bool shouldInsertMatchingText(const QChar &lookAhead) +MatchingText::MatchingText() +{ } + +bool MatchingText::shouldInsertMatchingText(const QTextCursor &tc) +{ + QTextDocument *doc = tc.document(); + return shouldInsertMatchingText(doc->characterAt(tc.selectionEnd())); +} + +bool MatchingText::shouldInsertMatchingText(const QChar &lookAhead) { switch (lookAhead.unicode()) { case '{': case '}': @@ -91,9 +100,6 @@ static bool shouldInsertMatchingText(const QChar &lookAhead) } // switch } -MatchingText::MatchingText() -{ } - QString MatchingText::insertMatchingBrace(const QTextCursor &cursor, const QString &textToProcess, const QChar &la, int *skippedChars) const { @@ -133,7 +139,7 @@ QString MatchingText::insertMatchingBrace(const QTextCursor &cursor, const QStri if (text.length() != 1) qWarning() << Q_FUNC_INFO << "handle event compression"; - if (isCompleteStringLiteral(tk, index - 1, startToken)) + if (isCompleteStringLiteral(tk, index - 1)) return QLatin1String("\""); return QString(); @@ -141,7 +147,7 @@ QString MatchingText::insertMatchingBrace(const QTextCursor &cursor, const QStri if (text.length() != 1) qWarning() << Q_FUNC_INFO << "handle event compression"; - if (isCompleteCharLiteral(tk, index - 1, startToken)) + if (isCompleteCharLiteral(tk, index - 1)) return QLatin1String("'"); return QString(); diff --git a/src/libs/cplusplus/MatchingText.h b/src/libs/cplusplus/MatchingText.h index cd3d59c5c16dadbd092d33ddaf33d5468530ce5b..26af99a8bea4803fdecda5efc0d1fb1f0269309b 100644 --- a/src/libs/cplusplus/MatchingText.h +++ b/src/libs/cplusplus/MatchingText.h @@ -41,6 +41,9 @@ class CPLUSPLUS_EXPORT MatchingText public: MatchingText(); + static bool shouldInsertMatchingText(const QTextCursor &tc); + static bool shouldInsertMatchingText(const QChar &lookAhead); + QString insertMatchingBrace(const QTextCursor &tc, const QString &text, const QChar &la, int *skippedChars) const; QString insertParagraphSeparator(const QTextCursor &tc) const; diff --git a/src/libs/cplusplus/SimpleLexer.cpp b/src/libs/cplusplus/SimpleLexer.cpp index 7e60f76115bc7e8a27adc30612dac06fa91fb0f3..59475bc4a4e78929fed5c0a4b2ec8eea602119f8 100644 --- a/src/libs/cplusplus/SimpleLexer.cpp +++ b/src/libs/cplusplus/SimpleLexer.cpp @@ -35,6 +35,17 @@ using namespace CPlusPlus; +SimpleToken::SimpleToken(const Token &token, const QStringRef &text) + : _kind(token.f.kind) + , _flags(0) + , _position(token.begin()) + , _length(token.f.length) + , _text(text) +{ + f._whitespace = token.f.whitespace; + f._newline = token.f.newline; +} + bool SimpleToken::isLiteral() const { return _kind >= T_FIRST_LITERAL && _kind <= T_LAST_LITERAL; @@ -60,6 +71,11 @@ bool SimpleToken::isObjCAtKeyword() const return _kind >= T_FIRST_OBJC_AT_KEYWORD && _kind <= T_LAST_OBJC_AT_KEYWORD; } +const char *SimpleToken::name() const +{ + return Token::name(_kind); +} + SimpleLexer::SimpleLexer() : _lastState(0), _skipComments(false), @@ -113,6 +129,7 @@ QList<SimpleToken> SimpleLexer::operator()(const QString &text, int state) Lexer lex(firstChar, lastChar); lex.setQtMocRunEnabled(_qtMocRunEnabled); lex.setObjCEnabled(_objCEnabled); + lex.setStartWithNewline(true); if (! _skipComments) lex.setScanCommentTokens(true); @@ -128,12 +145,8 @@ QList<SimpleToken> SimpleLexer::operator()(const QString &text, int state) if (tk.is(T_EOF_SYMBOL)) break; - SimpleToken simpleTk; - simpleTk._kind = int(tk.f.kind); - simpleTk._position = int(lex.tokenOffset()); - simpleTk._length = int(lex.tokenLength()); - simpleTk._text = text.midRef(simpleTk._position, simpleTk._length); - + QStringRef spell = text.midRef(lex.tokenOffset(), lex.tokenLength()); + SimpleToken simpleTk(tk, spell); lex.setScanAngleStringLiteralTokens(false); if (tk.f.newline && tk.is(T_POUND)) diff --git a/src/libs/cplusplus/SimpleLexer.h b/src/libs/cplusplus/SimpleLexer.h index 3f15193ee036e0b76050a22eb64734766687d979..0775eccb1c9162bc7c31ec2c29757aafecc948ba 100644 --- a/src/libs/cplusplus/SimpleLexer.h +++ b/src/libs/cplusplus/SimpleLexer.h @@ -37,21 +37,18 @@ namespace CPlusPlus { class SimpleLexer; +class Token; class CPLUSPLUS_EXPORT SimpleToken { public: - SimpleToken(int kind, int position, int length, const QStringRef &text) - : _kind(kind) - , _position(position) - , _length(length) - , _text(text) - { } + SimpleToken(const Token &token, const QStringRef &text); SimpleToken() - : _kind(0), - _position(0), - _length(0) + : _kind(0) + , _flags(0) + , _position(0) + , _length(0) { } inline int kind() const @@ -72,6 +69,12 @@ public: inline QStringRef text() const { return _text; } + inline bool followsNewline() const + { return f._newline; } + + inline bool followsWhitespace() const + { return f._whitespace; } + inline bool is(int k) const { return _kind == k; } inline bool isNot(int k) const { return _kind != k; } @@ -81,8 +84,27 @@ public: bool isComment() const; bool isObjCAtKeyword() const; + const char *name() const; + + // internal + inline void setPosition(int position) + { _position = position; } + + // internal + inline void setText(const QStringRef &text) + { _text = text; } + public: - int _kind; + short _kind; + union { + short _flags; + + struct { + short _newline: 1; + short _whitespace: 1; + } f; + }; + int _position; int _length; QStringRef _text; diff --git a/src/libs/utils/stylehelper.cpp b/src/libs/utils/stylehelper.cpp index 741486e89f6f9d8ad93d20eded72890bda883f4b..22ffa7e248eaebdd48ec90b2d3d79446bcc373ad 100644 --- a/src/libs/utils/stylehelper.cpp +++ b/src/libs/utils/stylehelper.cpp @@ -176,10 +176,11 @@ void StyleHelper::horizontalGradient(QPainter *painter, const QRect &spanRect, c QColor base = StyleHelper::baseColor(); QLinearGradient grad(rect.topLeft(), rect.bottomLeft()); - grad.setColorAt(0, highlightColor().lighter(120)); - grad.setColorAt(0.4, highlightColor()); - grad.setColorAt(0.401, base); + if (rect.height() == navigationWidgetHeight()) { + grad.setColorAt(0.4, highlightColor()); + grad.setColorAt(0.401, base); + } grad.setColorAt(1, shadowColor()); p->fillRect(rect, grad); diff --git a/src/plugins/cppeditor/cppeditor.cpp b/src/plugins/cppeditor/cppeditor.cpp index 2a681e858c514331a8ba32488909df83f2acea07..c6b860234e3f616ce2e264976564ef4541278078 100644 --- a/src/plugins/cppeditor/cppeditor.cpp +++ b/src/plugins/cppeditor/cppeditor.cpp @@ -53,6 +53,7 @@ #include <cplusplus/TokenUnderCursor.h> #include <cplusplus/TypeOfExpression.h> #include <cplusplus/MatchingText.h> +#include <cplusplus/BackwardsScanner.h> #include <cpptools/cppmodelmanagerinterface.h> #include <coreplugin/icore.h> @@ -1263,17 +1264,17 @@ bool CPPEditor::isElectricCharacter(const QChar &ch) const { if (ch == QLatin1Char('{') || ch == QLatin1Char('}') || + ch == QLatin1Char(':') || ch == QLatin1Char('#')) { return true; } return false; } -#if 1 QString CPPEditor::autoComplete(QTextCursor &cursor, const QString &textToInsert) const { - bool checkBlockEnd = m_allowSkippingOfBlockEnd; - m_allowSkippingOfBlockEnd = false; + const bool checkBlockEnd = m_allowSkippingOfBlockEnd; + m_allowSkippingOfBlockEnd = false; // consume blockEnd. if (!contextAllowsAutoParentheses(cursor)) return QString(); @@ -1281,16 +1282,21 @@ QString CPPEditor::autoComplete(QTextCursor &cursor, const QString &textToInsert QString text = textToInsert; const QChar lookAhead = characterAt(cursor.selectionEnd()); - QString autoText; + MatchingText matchingText; int skippedChars = 0; + const QString autoText = matchingText.insertMatchingBrace(cursor, text, lookAhead, &skippedChars); - if (checkBlockEnd && (lookAhead == QChar::ParagraphSeparator && (! text.isEmpty() && text.at(0) == QLatin1Char('}')))) { - skippedChars = 2; - text = text.mid(1); - } + if (checkBlockEnd && textToInsert.at(0) == QLatin1Char('}')) { + if (textToInsert.length() > 1) + qWarning() << "*** handle event compression"; - MatchingText matchingText; - autoText = matchingText.insertMatchingBrace(cursor, text, lookAhead, &skippedChars); + int startPos = cursor.selectionEnd(), pos = startPos; + while (characterAt(pos).isSpace()) + ++pos; + + if (characterAt(pos) == QLatin1Char('}')) + skippedChars += (pos - startPos) + 1; + } if (skippedChars) { const int pos = cursor.position(); @@ -1300,67 +1306,6 @@ QString CPPEditor::autoComplete(QTextCursor &cursor, const QString &textToInsert return autoText; } -#else -QString CPPEditor::autoComplete(QTextCursor &cursor, const QString &text) const -{ - bool checkBlockEnd = m_allowSkippingOfBlockEnd; - m_allowSkippingOfBlockEnd = false; - - if (!contextAllowsAutoParentheses(cursor)) - return QString(); - - QString autoText; - QChar lookAhead = characterAt(cursor.selectionEnd()); - if (lookAhead.isSpace() // Only auto-insert when the text right of the cursor seems unrelated - || lookAhead == QLatin1Char('{') - || lookAhead == QLatin1Char('}') - || lookAhead == QLatin1Char(']') - || lookAhead == QLatin1Char(')') - || lookAhead == QLatin1Char(';') - || lookAhead == QLatin1Char(',') - ) { - foreach (QChar c, text) { - QChar close; - if (c == QLatin1Char('(')) { - close = QLatin1Char(')'); - } else if (c == QLatin1Char('[')) - close = QLatin1Char(']'); - else if (c == QLatin1Char('\"')) - close = c; - else if (c == QLatin1Char('\'')) - close = c; - if (!close.isNull()) - autoText += close; - } - } - - bool skip = false; - QChar first = text.at(0); - if (first == QLatin1Char(')') - || first == QLatin1Char(']') - || first == QLatin1Char(';') - ) { - skip = (first == lookAhead); - } else if (first == QLatin1Char('\"') || first == QLatin1Char('\'')) { - if (first == lookAhead) { - QChar lookBehind = characterAt(cursor.position()-1); - skip = (lookBehind != '\\'); - } - } else if (checkBlockEnd && first == QLatin1Char('}') - && lookAhead == QChar::ParagraphSeparator) { - skip = (first == characterAt(cursor.position() + 1)); - cursor.movePosition(QTextCursor::Right); - } - - if (skip) { - int pos = cursor.position(); - cursor.setPosition(pos+1); - cursor.setPosition(pos, QTextCursor::KeepAnchor); - } - - return autoText; -} -#endif bool CPPEditor::autoBackspace(QTextCursor &cursor) { @@ -1398,7 +1343,6 @@ int CPPEditor::paragraphSeparatorAboutToBeInserted(QTextCursor &cursor) if (!contextAllowsAutoParentheses(cursor)) return 0; - // verify that we indeed do have an extra opening brace in the document int braceDepth = document()->lastBlock().userState(); if (braceDepth >= 0) @@ -1432,6 +1376,9 @@ int CPPEditor::paragraphSeparatorAboutToBeInserted(QTextCursor &cursor) bool CPPEditor::contextAllowsAutoParentheses(const QTextCursor &cursor) const { + if (! MatchingText::shouldInsertMatchingText(cursor)) + return false; + CPlusPlus::TokenUnderCursor tokenUnderCursor; const SimpleToken tk = tokenUnderCursor(cursor); @@ -1470,9 +1417,60 @@ static void indentCPPBlock(const CPPEditor::TabSettings &ts, void CPPEditor::indentBlock(QTextDocument *doc, QTextBlock block, QChar typedChar) { + QTextCursor tc(block); + tc.movePosition(QTextCursor::EndOfBlock); + + BackwardsScanner tk(tc, QString(), 400); + const int tokenCount = tk.startToken(); + const int indentSize = tabSettings().m_indentSize; + + if (tokenCount != 0) { + const SimpleToken firstToken = tk[0]; + + if (firstToken.is(T_COLON)) { + const int indent = tk.indentation(-1) + // indentation of the previous newline + indentSize; + tabSettings().indentLine(block, indent); + return; + } else if ((firstToken.is(T_PUBLIC) || firstToken.is(T_PROTECTED) || firstToken.is(T_PRIVATE) || + firstToken.is(T_Q_SIGNALS) || firstToken.is(T_Q_SLOTS)) && tk[1].is(T_COLON)) { + const int startOfBlock = tk.startOfBlock(0); + if (startOfBlock != 0) { + const int indent = tk.indentation(startOfBlock); + tabSettings().indentLine(block, indent); + return; + } + } else if (firstToken.is(T_CASE) || firstToken.is(T_DEFAULT)) { + const int startOfBlock = tk.startOfBlock(0); + if (startOfBlock != 0) { + const int indent = tk.indentation(startOfBlock); + tabSettings().indentLine(block, indent); + return; + } + return; + } + } + + if ((tokenCount == 0 || tk[0].isNot(T_POUND)) && typedChar.isNull() && (tk[-1].is(T_IDENTIFIER) || tk[-1].is(T_RPAREN))) { + int tokenIndex = -1; + if (tk[-1].is(T_RPAREN)) { + const int matchingBrace = tk.startOfMatchingBrace(0); + if (matchingBrace != 0 && tk[matchingBrace - 1].is(T_IDENTIFIER)) { + tokenIndex = matchingBrace - 1; + } + } + + const QString spell = tk.text(tokenIndex); + if (tk[tokenIndex].followsNewline() && (spell.startsWith(QLatin1String("QT_")) || + spell.startsWith(QLatin1String("Q_")))) { + const int indent = tk.indentation(tokenIndex); + tabSettings().indentLine(block, indent); + return; + } + } + const TextEditor::TextBlockIterator begin(doc->begin()); const TextEditor::TextBlockIterator end(block.next()); - indentCPPBlock(tabSettings(), block, begin, end, typedChar); } diff --git a/src/plugins/debugger/cdb/cdbdumperhelper.cpp b/src/plugins/debugger/cdb/cdbdumperhelper.cpp index 3e66d27d500c99df4b85a0d2845eda19aaff0a70..de6f3d1cd1662cb01df6e677c8c2385bcacf101f 100644 --- a/src/plugins/debugger/cdb/cdbdumperhelper.cpp +++ b/src/plugins/debugger/cdb/cdbdumperhelper.cpp @@ -554,7 +554,7 @@ static inline QString msgNotHandled(const QString &type) return QString::fromLatin1("The type '%1' is not handled.").arg(type); } -CdbDumperHelper::DumpResult CdbDumperHelper::dumpType(const WatchData &wd, bool dumpChildren, int source, +CdbDumperHelper::DumpResult CdbDumperHelper::dumpType(const WatchData &wd, bool dumpChildren, QList<WatchData> *result, QString *errorMessage) { // Check failure cache and supported types @@ -593,7 +593,7 @@ CdbDumperHelper::DumpResult CdbDumperHelper::dumpType(const WatchData &wd, bool arg(wd.name, wd.exp, wd.type); m_access->showDebuggerOutput(LogMisc, message); - const DumpExecuteResult der = executeDump(wd, td, dumpChildren, source, result, errorMessage); + const DumpExecuteResult der = executeDump(wd, td, dumpChildren, result, errorMessage); if (der == DumpExecuteOk) return DumpOk; // Cache types that fail due to complicated template size expressions. @@ -610,7 +610,7 @@ CdbDumperHelper::DumpResult CdbDumperHelper::dumpType(const WatchData &wd, bool CdbDumperHelper::DumpExecuteResult CdbDumperHelper::executeDump(const WatchData &wd, - const QtDumperHelper::TypeData& td, bool dumpChildren, int source, + const QtDumperHelper::TypeData& td, bool dumpChildren, QList<WatchData> *result, QString *errorMessage) { QByteArray inBuffer; @@ -658,12 +658,10 @@ CdbDumperHelper::DumpExecuteResult } if (!callDumper(callCmd, inBuffer, &outputData, true, errorMessage)) return DumpExecuteCallFailed; - QtDumperResult dumpResult; - if (!QtDumperHelper::parseValue(outputData, &dumpResult)) { + if (!QtDumperHelper::parseValue(outputData, result)) { *errorMessage = QLatin1String("Parsing of value query output failed."); return DumpExecuteCallFailed; } - *result = dumpResult.toWatchData(source); return DumpExecuteOk; } diff --git a/src/plugins/debugger/cdb/cdbdumperhelper.h b/src/plugins/debugger/cdb/cdbdumperhelper.h index 5c7530a7a7b32ea014aa9529619c3adff8fe41ae..c9895e08d96b4c6f55141344ecc544d7da838d79 100644 --- a/src/plugins/debugger/cdb/cdbdumperhelper.h +++ b/src/plugins/debugger/cdb/cdbdumperhelper.h @@ -89,7 +89,7 @@ public: // Dump a WatchData item. enum DumpResult { DumpNotHandled, DumpOk, DumpError }; - DumpResult dumpType(const WatchData &d, bool dumpChildren, int source, + DumpResult dumpType(const WatchData &d, bool dumpChildren, QList<WatchData> *result, QString *errorMessage); inline CdbComInterfaces *comInterfaces() const { return m_cif; } @@ -113,7 +113,7 @@ private: DumpComplexExpressionEncountered, DumpExecuteCallFailed }; DumpExecuteResult executeDump(const WatchData &wd, - const QtDumperHelper::TypeData& td, bool dumpChildren, int source, + const QtDumperHelper::TypeData& td, bool dumpChildren, QList<WatchData> *result, QString *errorMessage); static bool writeToDebuggee(CIDebugDataSpaces *ds, const QByteArray &buffer, quint64 address, QString *errorMessage); diff --git a/src/plugins/debugger/cdb/cdbstackframecontext.cpp b/src/plugins/debugger/cdb/cdbstackframecontext.cpp index 8938f93e48aab21eeeee62d1227a0b47d260a664..1b9b18a04f0ae6574dd9c0d5be14453cc2402d2d 100644 --- a/src/plugins/debugger/cdb/cdbstackframecontext.cpp +++ b/src/plugins/debugger/cdb/cdbstackframecontext.cpp @@ -156,7 +156,7 @@ bool WatchHandleDumperInserter::expandPointerToDumpable(const WatchData &wd, QSt derefedWd.name = QString(QLatin1Char('*')); derefedWd.iname = wd.iname + QLatin1String(".*"); derefedWd.source = OwnerDumper | CdbStackFrameContext::ChildrenKnownBit; - const CdbDumperHelper::DumpResult dr = m_dumper->dumpType(derefedWd, true, OwnerDumper, &m_dumperResult, errorMessage); + const CdbDumperHelper::DumpResult dr = m_dumper->dumpType(derefedWd, true, &m_dumperResult, errorMessage); if (dr != CdbDumperHelper::DumpOk) break; // Insert the pointer item with 1 additional child + its dumper results @@ -166,8 +166,7 @@ bool WatchHandleDumperInserter::expandPointerToDumpable(const WatchData &wd, QSt ptrWd.setHasChildren(true); ptrWd.setChildrenUnneeded(); m_wh->insertData(ptrWd); - foreach(const WatchData &dwd, m_dumperResult) - m_wh->insertData(dwd); + m_wh->insertBulkData(m_dumperResult); handled = true; } while (false); if (debugCDBWatchHandling) @@ -184,7 +183,8 @@ static inline void fixDumperResult(const WatchData &source, const int size = result->size(); if (!size) return; - // debugWatchDataList(*result, suppressGrandChildren ? ">fixDumperResult suppressGrandChildren" : ">fixDumperResult"); + if (debugCDBWatchHandling) + debugWatchDataList(*result, suppressGrandChildren ? ">fixDumperResult suppressGrandChildren" : ">fixDumperResult"); WatchData &returned = result->front(); if (returned.iname != source.iname) return; @@ -198,6 +198,10 @@ static inline void fixDumperResult(const WatchData &source, returned.setValue(QCoreApplication::translate("CdbStackFrameContext", "<Unknown>")); } } + // Indicate owner and known children + returned.source = OwnerDumper; + if (returned.isChildrenKnown() && returned.isHasChildrenKnown() && returned.hasChildren) + returned.source |= CdbStackFrameContext::ChildrenKnownBit; if (size == 1) return; // If the model queries the expanding item by pretending childrenNeeded=1, @@ -208,6 +212,10 @@ static inline void fixDumperResult(const WatchData &source, QList<WatchData>::iterator it = result->begin(); for (++it; it != wend; ++it) { WatchData &wd = *it; + // Indicate owner and known children + it->source = OwnerDumper; + if (it->isChildrenKnown() && it->isHasChildrenKnown() && it->hasChildren) + it->source |= CdbStackFrameContext::ChildrenKnownBit; if (wd.addr.isEmpty() && wd.isSomethingNeeded()) { wd.setHasChildren(false); wd.setAllUnneeded(); @@ -218,7 +226,8 @@ static inline void fixDumperResult(const WatchData &source, wd.setHasChildren(false); } } - // debugWatchDataList(*result, "<fixDumperResult"); + if (debugCDBWatchHandling) + debugWatchDataList(*result, "<fixDumperResult"); } WatchHandleDumperInserter &WatchHandleDumperInserter::operator=(WatchData &wd) @@ -238,15 +247,14 @@ WatchHandleDumperInserter &WatchHandleDumperInserter::operator=(WatchData &wd) return *this; } // Try library dumpers. - switch (m_dumper->dumpType(wd, true, OwnerDumper, &m_dumperResult, &errorMessage)) { + switch (m_dumper->dumpType(wd, true, &m_dumperResult, &errorMessage)) { case CdbDumperHelper::DumpOk: if (debugCDBWatchHandling) qDebug() << "dumper triggered"; // Dumpers omit types for complicated templates fixDumperResult(wd, &m_dumperResult, false); // Discard the original item and insert the dumper results - foreach(const WatchData &dwd, m_dumperResult) - m_wh->insertData(dwd); + m_wh->insertBulkData(m_dumperResult); // Nasty side effect: Modify owner for the ignore predicate wd.source = OwnerDumper; break; @@ -325,13 +333,12 @@ bool CdbStackFrameContext::completeData(const WatchData &incompleteLocal, return true; } QList<WatchData> dumperResult; - const CdbDumperHelper::DumpResult dr = m_dumper->dumpType(incompleteLocal, true, OwnerDumper, &dumperResult, errorMessage); + const CdbDumperHelper::DumpResult dr = m_dumper->dumpType(incompleteLocal, true, &dumperResult, errorMessage); if (dr == CdbDumperHelper::DumpOk) { // Hack to stop endless model recursion const bool suppressGrandChildren = !wh->isExpandedIName(incompleteLocal.iname); fixDumperResult(incompleteLocal, &dumperResult, suppressGrandChildren); - foreach(const WatchData &dwd, dumperResult) - wh->insertData(dwd); + wh->insertBulkData(dumperResult); } else { const QString msg = QString::fromLatin1("Unable to further expand dumper watch data: '%1' (%2): %3/%4").arg(incompleteLocal.name, incompleteLocal.type).arg(int(dr)).arg(*errorMessage); qWarning("%s", qPrintable(msg)); @@ -372,7 +379,7 @@ bool CdbStackFrameContext::editorToolTip(const QString &iname, // Check dumpers. Should actually be just one item. if (m_useDumpers && m_dumper->state() != CdbDumperHelper::Disabled) { QList<WatchData> result; - if (CdbDumperHelper::DumpOk == m_dumper->dumpType(wd, false, OwnerDumper, &result, errorMessage)) { + if (CdbDumperHelper::DumpOk == m_dumper->dumpType(wd, false, &result, errorMessage)) { foreach (const WatchData &dwd, result) { if (!value->isEmpty()) value->append(QLatin1Char('\n')); diff --git a/src/plugins/debugger/cdb/cdbsymbolgroupcontext.cpp b/src/plugins/debugger/cdb/cdbsymbolgroupcontext.cpp index ee941972cb00119f854eabd1a775da74b23e5272..f58f1f745272a9912e89d72b23cf473b4e2e997f 100644 --- a/src/plugins/debugger/cdb/cdbsymbolgroupcontext.cpp +++ b/src/plugins/debugger/cdb/cdbsymbolgroupcontext.cpp @@ -595,9 +595,9 @@ bool CdbSymbolGroupContext::debugValueToInteger(const DEBUG_VALUE &dv, qint64 *v * To add further types, have a look at the toString() output of the * symbol group. */ -static QString msgStructuralError(const QString &type, int code) +static QString msgStructuralError(const QString &name, const QString &type, int code) { - return QString::fromLatin1("Warning: Internal dumper for '%1' failed with %2.").arg(type).arg(code); + return QString::fromLatin1("Warning: Internal dumper for '%1' (%2) failed with %3.").arg(name, type).arg(code); } static inline bool isStdStringOrPointer(const QString &type) @@ -631,7 +631,7 @@ CdbSymbolGroupContext::DumperResult rc = DumperError; break; default: - qWarning("%s\n", qPrintable(msgStructuralError(wd->type, drc))); + qWarning("%s\n", qPrintable(msgStructuralError(wd->iname, wd->type, drc))); rc = DumperNotHandled; break; } @@ -647,7 +647,7 @@ CdbSymbolGroupContext::DumperResult rc = DumperError; break; default: - qWarning("%s\n", qPrintable(msgStructuralError(wd->type, drc))); + qWarning("%s\n", qPrintable(msgStructuralError(wd->iname, wd->type, drc))); rc = DumperNotHandled; break; } diff --git a/src/plugins/debugger/gdb/gdbengine.cpp b/src/plugins/debugger/gdb/gdbengine.cpp index faa860a1467347db717391317eaf7b445bb562bd..3844f0af683e1c75572cf2ada9a3492c35a6ff2d 100644 --- a/src/plugins/debugger/gdb/gdbengine.cpp +++ b/src/plugins/debugger/gdb/gdbengine.cpp @@ -3305,36 +3305,12 @@ static void parseSizeCache(const GdbMi &contents, QtDumperHelper *dumperHelper) void GdbEngine::handleQueryDebuggingHelper(const GdbResultRecord &record, const QVariant &) { const double dumperVersionRequired = 1.0; - m_dumperHelper.clear(); //qDebug() << "DATA DUMPER TRIAL:" << record.toString(); GdbMi contents; QTC_ASSERT(parseConsoleStream(record, &contents), /**/); - GdbMi simple = contents.findChild("dumpers"); - - m_dumperHelper.setQtNamespace(_(contents.findChild("namespace").data())); - GdbMi qtversion = contents.findChild("qtversion"); - int qtv = 0; - if (qtversion.children().size() == 3) { - qtv = (qtversion.childAt(0).data().toInt() << 16) - + (qtversion.childAt(1).data().toInt() << 8) - + qtversion.childAt(2).data().toInt(); - //qDebug() << "FOUND QT VERSION:" << qtversion.toString() << m_qtVersion; - } - m_dumperHelper.setQtVersion(qtv); - //qDebug() << "CONTENTS:" << contents.toString(); - //qDebug() << "SIMPLE DUMPERS:" << simple.toString(); - - QStringList availableSimpleDebuggingHelpers; - foreach (const GdbMi &item, simple.children()) - availableSimpleDebuggingHelpers.append(_(item.data())); - m_dumperHelper.parseQueryTypes(availableSimpleDebuggingHelpers, QtDumperHelper::GdbDebugger); - - if (availableSimpleDebuggingHelpers.isEmpty()) { - if (!m_dumperInjectionLoad) // Retry if thread has not terminated yet. - m_debuggingHelperState = DebuggingHelperUnavailable; - showStatusMessage(tr("Debugging helpers not found.")); - } else { + const bool ok = m_dumperHelper.parseQuery(contents, QtDumperHelper::GdbDebugger) && m_dumperHelper.typeCount(); + if (ok) { // Get version and sizes from dumpers. Expression cache // currently causes errors. const double dumperVersion = getDumperVersion(contents); @@ -3347,6 +3323,10 @@ void GdbEngine::handleQueryDebuggingHelper(const GdbResultRecord &record, const m_debuggingHelperState = DebuggingHelperAvailable; const QString successMsg = tr("Dumper version %1, %n custom dumpers found.", 0, m_dumperHelper.typeCount()).arg(dumperVersion); showStatusMessage(successMsg); + } else { + if (!m_dumperInjectionLoad) // Retry if thread has not terminated yet. + m_debuggingHelperState = DebuggingHelperUnavailable; + showStatusMessage(tr("Debugging helpers not found.")); } //qDebug() << m_dumperHelper.toString(true); //qDebug() << m_availableSimpleDebuggingHelpers << "DATA DUMPERS AVAILABLE"; @@ -4318,7 +4298,8 @@ IDebuggerEngine *createSymbianEngine(DebuggerManager *parent, QSharedPointer<TrkOptions> options(new TrkOptions); options->fromSettings(Core::ICore::instance()->settings()); - opts->push_back(new TrkOptionsPage(options)); + if (!qgetenv("QTCREATOR_WITH_S60").isEmpty()) + opts->push_back(new TrkOptionsPage(options)); TrkGdbAdapter *adapter = new TrkGdbAdapter(options); GdbEngine *engine = new GdbEngine(parent, adapter); QObject::connect(adapter, SIGNAL(output(QString)), diff --git a/src/plugins/debugger/watchhandler.cpp b/src/plugins/debugger/watchhandler.cpp index 8e71dae9610d881cf26fb92b45e327072a151b35..ac52e47baa369ee5055bf947f5c70d1d0daa5af5 100644 --- a/src/plugins/debugger/watchhandler.cpp +++ b/src/plugins/debugger/watchhandler.cpp @@ -227,6 +227,8 @@ QString WatchData::toString() const str << QLatin1Char('{'); if (!iname.isEmpty()) str << "iname=\"" << iname << doubleQuoteComma; + if (!name.isEmpty() && name != iname) + str << "name=\"" << name << doubleQuoteComma; if (!addr.isEmpty()) str << "addr=\"" << addr << doubleQuoteComma; if (!exp.isEmpty()) diff --git a/src/plugins/debugger/watchutils.cpp b/src/plugins/debugger/watchutils.cpp index 7b70b5845d325c4e94ceefbe6cd820ca6917666c..d09544fcab38d839808f5d4d604ed443f31d6390 100644 --- a/src/plugins/debugger/watchutils.cpp +++ b/src/plugins/debugger/watchutils.cpp @@ -29,6 +29,7 @@ #include "watchutils.h" #include "watchhandler.h" +#include "gdb/gdbmi.h" #include <utils/qtcassert.h> #include <texteditor/basetexteditor.h> @@ -491,172 +492,6 @@ QString cppExpressionAt(TextEditor::ITextEditor *editor, int pos, return expr; } -// --------------- QtDumperResult - -QtDumperResult::Child::Child() : - keyEncoded(0), - valueEncoded(0), - childCount(-1), - valueEnabled(true), - valueEncountered(false) -{ -} - -QtDumperResult::QtDumperResult() : - valueEncountered(false), - valueEncoded(0), - valueEnabled(true), - childCount(-1), - internal(false), - childChildCount(-1) -{ -} - -void QtDumperResult::clear() -{ - iname.clear(); - value.clear(); - address.clear(); - addressInfo.clear(); - type.clear(); - extra.clear(); - displayedType.clear(); - valueEncoded = 0; - valueEncountered = false; - valueEnabled = false; - childCount = -1; - internal = false; - childType.clear(); - children.clear(); - childChildCount = -1; -} - -QList<WatchData> QtDumperResult::toWatchData(int source) const -{ - QList<WatchData> rc; - rc.push_back(WatchData()); - WatchData &root = rc.front(); - root.iname = iname; - const QChar dot = QLatin1Char('.'); - const int lastDotIndex = root.iname.lastIndexOf(dot); - root.exp = root.name = lastDotIndex == -1 ? iname : iname.mid(lastDotIndex + 1); - if (valueEncountered) { - root.setValue(decodeData(value, valueEncoded)); - root.valueEnabled = valueEnabled; - } - root.setType(type); - if (!displayedType.isEmpty()) - root.displayedType = displayedType; - root.setAddress(address); - root.source = source; - if (childCount >= 0) - root.setHasChildren(childCount > 0); - // Children. Sanity check after parsing sets childcount to list size - // if list is not empty - if (children.empty()) { - if (childCount > 0) - root.setChildrenNeeded(); - } else { - root.setChildrenUnneeded(); - for (int c = 0; c < childCount; c++) { - const Child &dchild = children.at(c); - rc.push_back(WatchData()); - WatchData &wchild = rc.back(); - wchild.source = source; - wchild.iname = iname; - // Name can be empty for array-like things - const QString iname = dchild.name.isEmpty() ? QString::number(c) : dchild.name; - // Use key entry as name (which is used for map nodes) - if (dchild.key.isEmpty()) { - wchild.name = iname; - } else { - // Do not use map keys as iname since they might contain quotes. - wchild.name = decodeData(dchild.key, dchild.keyEncoded); - if (wchild.name.size() > 13) { - wchild.name.truncate(12); - wchild.name += QLatin1String("..."); - } - } - // Append iname to total iname. - wchild.iname += dot; - wchild.iname += iname; - wchild.exp = dchild.exp; - if (dchild.valueEncountered) { - wchild.valueEnabled = dchild.valueEnabled; - wchild.setValue(decodeData(dchild.value, dchild.valueEncoded)); - } - wchild.setAddress(dchild.address); - // The type setter sets hasChildren for known types. - wchild.setType(dchild.type.isEmpty() ? childType : dchild.type); - if (!dchild.displayedType.isEmpty()) - wchild.displayedType = dchild.displayedType; - // Child overrides. - const int effectiveChildChildCount = dchild.childCount == -1 ? childChildCount : dchild.childCount; - switch (effectiveChildChildCount) { - case -1: // In this case, trust WatchData::setType(). - break; - case 0: - wchild.setHasChildren(false); - break; - default: - wchild.setHasChildren(true); - wchild.setChildrenNeeded(); - break; - } - } - } - if (debug) { - QDebug nospace = qDebug().nospace(); - nospace << "QtDumperResult::toWatchData" << *this << '\n'; - foreach(const WatchData &wd, rc) - nospace << " " << wd.toString() << '\n'; - } - - return rc; -} - -QDebug operator<<(QDebug in, const QtDumperResult &d) -{ - QDebug nospace = in.nospace(); - nospace << " iname=" << d.iname << " type=" << d.type - << " displayed=" << d.displayedType - << " address=" << d.address; - if (!d.addressInfo.isEmpty()) - nospace << " addressInfo=" << d.addressInfo; - if (d.valueEncountered) { - nospace << " encoded=" << d.valueEncoded - << " value=" << d.value - << " enabled=" << d.valueEnabled; - } else { - nospace << " <no value>"; - } - nospace << " childnumchild=" << d.childChildCount - << " internal=" << d.internal - << " extra='" << d.extra << "'\n"; - - const int realChildCount = d.children.size(); - if (d.childCount || realChildCount) { - nospace << "childCount=" << d.childCount << '/' << realChildCount - << " childType=" << d.childType << '\n'; - for (int i = 0; i < realChildCount; i++) { - const QtDumperResult::Child &c = d.children.at(i); - nospace << " #" << i << " addr=" << c.address - << " enabled=" << c.valueEnabled - << " type=" << c.type << " exp=" << c.exp - << " name=" << c.name; - if (!c.key.isEmpty()) - nospace << " keyencoded=" << c.keyEncoded << " key=" << c.key; - if (c.valueEncountered) { - nospace << " valueencoded=" << c.valueEncoded << " value=" << c.value; - } else { - nospace << " <no value>"; - } - nospace << "childcount=" << c.childCount << '\n'; - } - } - return in; -} - // ----------------- QtDumperHelper::TypeData QtDumperHelper::TypeData::TypeData() : type(UnknownType), @@ -725,6 +560,10 @@ QString QtDumperHelper::toString(bool debug) const for (SizeCache::const_iterator it = m_sizeCache.constBegin(); it != scend; ++it) { str << ' ' << it.key() << '=' << it.value(); } + str << "\nExpression cache: (" << m_expressionCache.size() << ")\n"; + const QMap<QString, QString>::const_iterator excend = m_expressionCache.constEnd(); + for (QMap<QString, QString>::const_iterator it = m_expressionCache.constBegin(); it != excend; ++it) + str << " " << it.key() << ' ' << it.value() << '\n'; return rc; } const QString nameSpace = m_qtNamespace.isEmpty() ? QCoreApplication::translate("QtDumperHelper", "<none>") : m_qtNamespace; @@ -749,11 +588,6 @@ QString QtDumperHelper::qtNamespace() const return m_qtNamespace; } -void QtDumperHelper::setQtNamespace(const QString &qtNamespace) -{ - m_qtNamespace = qtNamespace; -} - int QtDumperHelper::typeCount() const { return m_nameTypeMap.size(); @@ -842,23 +676,6 @@ QString QtDumperHelper::qtVersionString() const return rc; } -void QtDumperHelper::setQtVersion(int v) -{ - m_qtVersion = v; -} - -void QtDumperHelper::setQtVersion(const QString &v) -{ - m_qtVersion = 0; - const QStringList vl = v.split(QLatin1Char('.')); - if (vl.size() == 3) { - const int major = vl.at(0).toInt(); - const int minor = vl.at(1).toInt(); - const int patch = vl.at(2).toInt(); - m_qtVersion = (major << 16) | (minor << 8) | patch; - } -} - // Parse a list of types. void QtDumperHelper::parseQueryTypes(const QStringList &l, Debugger debugger) { @@ -1049,134 +866,6 @@ bool DumperParser::handleValue(const char *k, int size) return true; } -/* Parse 'query' (1) protocol response of the custom dumpers: - * "'dumpers=["QByteArray","QDateTime",..."std::basic_string",], - * qtversion=["4","5","1"],namespace="""' */ - -class QueryDumperParser : public DumperParser { -public: - typedef QPair<QString, int> SizeEntry; - explicit QueryDumperParser(const char *s); - - struct Data { - QString qtNameSpace; - QString qtVersion; - QString dumperVersion; - QStringList types; - QList<SizeEntry> sizes; - QMap<QString, QString> expressionCache; - }; - - inline Data data() const { return m_data; } - -protected: - virtual bool handleKeyword(const char *k, int size); - virtual bool handleListStart(); - virtual bool handleListEnd(); - virtual bool handleHashEnd(); - virtual bool handleValue(const char *k, int size); - -private: - enum Mode { None, ExpectingDumpers, ExpectingQtVersion, ExpectingDumperVersion, - ExpectingNameSpace, ExpectingSizes, ExpectingExpressionCache }; - Mode m_mode; - Data m_data; - QString m_lastSizeType; - QString m_lastExpression; -}; - -QueryDumperParser::QueryDumperParser(const char *s) : - DumperParser(s), - m_mode(None) -{ -} - -bool QueryDumperParser::handleKeyword(const char *k, int size) -{ - switch (m_mode) { - case ExpectingSizes: - m_lastSizeType = QString::fromLatin1(k, size); - return true; - case ExpectingExpressionCache: - m_lastExpression = QString::fromLatin1(k, size); - return true; - default: - break; - } - if (!qstrncmp(k, "dumpers", size)) { - m_mode = ExpectingDumpers; - return true; - } - if (!qstrncmp(k, "qtversion", size)) { - m_mode = ExpectingQtVersion; - return true; - } - if (!qstrncmp(k, "dumperversion", size)) { - m_mode = ExpectingDumperVersion; - return true; - } - if (!qstrncmp(k, "namespace", size)) { - m_mode = ExpectingNameSpace; - return true; - } - if (!qstrncmp(k, "sizes", size)) { - m_mode = ExpectingSizes; - return true; - } - if (!qstrncmp(k, "expressions", size)) { - m_mode = ExpectingExpressionCache; - return true; - } - qWarning("%s Unexpected keyword %s.\n", Q_FUNC_INFO, QByteArray(k, size).constData()); - return false; -} - -bool QueryDumperParser::handleListStart() -{ - return m_mode == ExpectingDumpers || m_mode == ExpectingQtVersion; -} - -bool QueryDumperParser::handleListEnd() -{ - m_mode = None; - return true; -} - -bool QueryDumperParser::handleHashEnd() -{ - m_mode = None; // Size hash - return true; -} - -bool QueryDumperParser::handleValue(const char *k, int size) -{ - switch (m_mode) { - case None: - return false; - case ExpectingDumpers: - m_data.types.push_back(QString::fromLatin1(k, size)); - break; - case ExpectingNameSpace: - m_data.qtNameSpace = QString::fromLatin1(k, size); - break; - case ExpectingDumperVersion: - m_data.dumperVersion = QString::fromLatin1(k, size); - break; - case ExpectingQtVersion: // ["4","1","5"] - if (!m_data.qtVersion.isEmpty()) - m_data.qtVersion += QLatin1Char('.'); - m_data.qtVersion += QString::fromLatin1(k, size); - break; - case ExpectingSizes: - m_data.sizes.push_back(SizeEntry(m_lastSizeType, QString::fromLatin1(k, size).toInt())); - break; - case ExpectingExpressionCache: - m_data.expressionCache.insert(m_lastExpression, QString::fromLatin1(k, size)); - break; - } - return true; -} - static inline QString qClassName(const QString &qtNamespace, const char *className) { if (qtNamespace.isEmpty()) @@ -1194,36 +883,73 @@ void QtDumperHelper::setQClassPrefixes(const QString &qNamespace) m_qSharedPointerPrefix = qClassName(qNamespace, "QSharedPointer"); m_qSharedDataPointerPrefix = qClassName(qNamespace, "QSharedDataPointer"); m_qWeakPointerPrefix = qClassName(qNamespace, "QWeakPointer"); + m_qListPrefix = qClassName(qNamespace, "QList"); + m_qLinkedListPrefix = qClassName(qNamespace, "QLinkedList"); + m_qVectorPrefix = qClassName(qNamespace, "QVector"); } -// parse a query -bool QtDumperHelper::parseQuery(const char *data, Debugger debugger) +static inline double getDumperVersion(const GdbMi &contents) { - QueryDumperParser parser(data); - if (!parser.run()) - return false; - clear(); - m_qtNamespace = parser.data().qtNameSpace; - setQtVersion(parser.data().qtVersion); - setQClassPrefixes(m_qtNamespace); - parseQueryTypes(parser.data().types, debugger); - foreach (const QueryDumperParser::SizeEntry &se, parser.data().sizes) - addSize(se.first, se.second); - m_expressionCache = parser.data().expressionCache; - // Version - if (!parser.data().dumperVersion.isEmpty()) { - double dumperVersion; + const GdbMi dumperVersionG = contents.findChild("dumperversion"); + if (dumperVersionG.type() != GdbMi::Invalid) { bool ok; - dumperVersion = parser.data().dumperVersion.toDouble(&ok); + const double v = QString::fromAscii(dumperVersionG.data()).toDouble(&ok); if (ok) - m_dumperVersion = dumperVersion; + return v; } + return 1.0; +} + +bool QtDumperHelper::parseQuery(const GdbMi &contents, Debugger debugger) +{ + clear(); + if (debug > 1) + qDebug() << "parseQuery" << contents.toString(true, 2); + + // Common info, dumper version, etc + m_qtNamespace = QLatin1String(contents.findChild("namespace").data()); + int qtv = 0; + const GdbMi qtversion = contents.findChild("qtversion"); + if (qtversion.children().size() == 3) { + qtv = (qtversion.childAt(0).data().toInt() << 16) + + (qtversion.childAt(1).data().toInt() << 8) + + qtversion.childAt(2).data().toInt(); + } + m_qtVersion = qtv; + // Get list of helpers + QStringList availableSimpleDebuggingHelpers; + foreach (const GdbMi &item, contents.findChild("dumpers").children()) + availableSimpleDebuggingHelpers.append(QLatin1String(item.data())); + parseQueryTypes(availableSimpleDebuggingHelpers, debugger); + m_dumperVersion = getDumperVersion(contents); + // Parse sizes + foreach (const GdbMi &sizesList, contents.findChild("sizes").children()) { + const int childCount = sizesList.childCount(); + if (childCount > 1) { + const int size = sizesList.childAt(0).data().toInt(); + for (int c = 1; c < childCount; c++) + addSize(QLatin1String(sizesList.childAt(c).data()), size); + } + } + // Parse expressions + foreach (const GdbMi &exprList, contents.findChild("expressions").children()) + if (exprList.childCount() == 2) + m_expressionCache.insert(QLatin1String(exprList.childAt(0).data()), + QLatin1String(exprList.childAt(1).data())); return true; } -void QtDumperHelper::addExpression(const QString &expression, const QString &value) +// parse a query +bool QtDumperHelper::parseQuery(const char *data, Debugger debugger) { - m_expressionCache.insert(expression, value); + QByteArray fullData = data; + fullData.insert(0, '{'); + fullData.append(data); + fullData.append('}'); + GdbMi root(fullData); + if (!root.isValid()) + return false; + return parseQuery(root, debugger); } void QtDumperHelper::addSize(const QString &name, int size) @@ -1316,6 +1042,14 @@ QtDumperHelper::SpecialSizeType QtDumperHelper::specialSizeType(const QString &t return QSharedDataPointerSize; if (typeName.startsWith(m_qWeakPointerPrefix)) return QWeakPointerSize; + if (typeName.startsWith(m_qListPrefix)) + return QListSize; + if (typeName.startsWith(m_qLinkedListPrefix)) + return QLinkedListSize; + if (typeName.startsWith(m_qVectorPrefix)) + return QVectorSize; + if (typeName.startsWith(m_qQueuePrefix)) + return QQueueSize; return SpecialSizeCount; } @@ -1504,233 +1238,173 @@ void QtDumperHelper::evaluationParameters(const WatchData &data, qDebug() << '\n' << Q_FUNC_INFO << '\n' << data.toString() << "\n-->" << outertype << td.type << extraArgs; } -/* Parse value: - * "iname="local.sl",addr="0x0012BA84",value="<3 items>",valuedisabled="true", - * numchild="3",childtype="QString",childnumchild="0", - * children=[{name="0",value="<binhex>",valueencoded="2"}, - * {name="1",value="dAB3AG8A",valueencoded="2"}, - * {name="2",value="dABoAHIAZQBlAA==",valueencoded="2"}]" */ - -class ValueDumperParser : public DumperParser -{ -public: - explicit ValueDumperParser(const char *s); - - inline QtDumperResult result() const { return m_result; } +// GdbMi parsing helpers for parsing dumper value results -protected: - virtual bool handleKeyword(const char *k, int size); - virtual bool handleHashStart(); - virtual bool handleValue(const char *k, int size); - -private: - enum Mode { None, ExpectingIName, ExpectingAddress, ExpectingValue, - ExpectingType, ExpectingDisplayedType, ExpectingInternal, - ExpectingValueEnabled, ExpectingValueEncoded, - ExpectingCommonChildType, ExpectingChildCount, - ExpectingChildChildOverrideCount, - ExpectingExtra, - IgnoreNext, - ChildModeStart, - ExpectingChildren,ExpectingChildName, ExpectingChildAddress, - ExpectingChildExpression, ExpectingChildType, - ExpectingChildDisplayedType, - ExpectingChildKey, ExpectingChildKeyEncoded, - ExpectingChildValue, ExpectingChildValueEncoded, - ExpectingChildValueEnabled, ExpectingChildChildCount, - IgnoreNextChildMode - }; - - static inline Mode nextMode(Mode in, const char *keyword, int size); - - Mode m_mode; - QtDumperResult m_result; -}; - -ValueDumperParser::ValueDumperParser(const char *s) : - DumperParser(s), - m_mode(None) +static bool gdbMiGetIntValue(int *target, + const GdbMi &node, + const char *child) { + *target = -1; + const GdbMi childNode = node.findChild(child); + if (!childNode.isValid()) + return false; + bool ok; + *target = childNode.data().toInt(&ok); + return ok; } -// Check key words -ValueDumperParser::Mode ValueDumperParser::nextMode(Mode in, const char *keyword, int size) +// Find a string child node and assign value if it exists. +// Optionally decode. +static bool gdbMiGetStringValue(QString *target, + const GdbMi &node, + const char *child, + const char *encodingChild = 0) { - // Careful with same prefix - switch (size) { - case 3: - if (!qstrncmp(keyword, "exp", size)) - return ExpectingChildExpression; - if (!qstrncmp(keyword, "key", size)) - return ExpectingChildKey; - break; - case 4: - if (!qstrncmp(keyword, "addr", size)) - return in > ChildModeStart ? ExpectingChildAddress : ExpectingAddress; - if (!qstrncmp(keyword, "type", size)) - return in > ChildModeStart ? ExpectingChildType : ExpectingType; - if (!qstrncmp(keyword, "name", size)) - return ExpectingChildName; - break; - case 5: - if (!qstrncmp(keyword, "iname", size)) - return ExpectingIName; - if (!qstrncmp(keyword, "value", size)) - return in > ChildModeStart ? ExpectingChildValue : ExpectingValue; - if (!qstrncmp(keyword, "extra", size)) - return ExpectingExtra; - break; - case 8: - if (!qstrncmp(keyword, "children", size)) - return ExpectingChildren; - if (!qstrncmp(keyword, "numchild", size)) - return in > ChildModeStart ? ExpectingChildChildCount : ExpectingChildCount; - if (!qstrncmp(keyword, "internal", size)) - return ExpectingInternal; - break; - case 9: - if (!qstrncmp(keyword, "childtype", size)) - return ExpectingCommonChildType; - break; - case 10: - if (!qstrncmp(keyword, "keyencoded", size)) - return ExpectingChildKeyEncoded; - break; - case 12: - if (!qstrncmp(keyword, "valueencoded", size)) - return in > ChildModeStart ? ExpectingChildValueEncoded : ExpectingValueEncoded; - break; - case 13: - if (!qstrncmp(keyword, "valueenabled", size)) - return in > ChildModeStart ? ExpectingChildValueEnabled : ExpectingValueEnabled; - if (!qstrncmp(keyword, "displayedtype", size)) - return in > ChildModeStart ? ExpectingChildDisplayedType : ExpectingDisplayedType; - if (!qstrncmp(keyword, "childnumchild", size)) - return ExpectingChildChildOverrideCount; - break; + target->clear(); + const GdbMi childNode = node.findChild(child); + if (!childNode.isValid()) + return false; + // Encoded data + if (encodingChild) { + int encoding; + if (!gdbMiGetIntValue(&encoding, node, encodingChild)) + encoding = 0; + *target = decodeData(childNode.data(), encoding); + return true; } - return in > ChildModeStart ? IgnoreNextChildMode : IgnoreNext; -} - -bool ValueDumperParser::handleKeyword(const char *k, int size) -{ - const Mode newMode = nextMode(m_mode, k, size); - if (debug && newMode == IgnoreNext) - qWarning("%s Unexpected keyword %s.\n", Q_FUNC_INFO, QByteArray(k, size).constData()); - m_mode = newMode; + // Plain data + *target = QLatin1String(childNode.data()); return true; } -bool ValueDumperParser::handleHashStart() +static bool gdbMiGetBoolValue(bool *target, + const GdbMi &node, + const char *child) { - m_result.children.push_back(QtDumperResult::Child()); + *target = false; + const GdbMi childNode = node.findChild(child); + if (!childNode.isValid()) + return false; + *target = childNode.data() == "true"; return true; } -bool ValueDumperParser::handleValue(const char *k, int size) +/* Context to store parameters that influence the next level children. + * (next level only, it is not further inherited). For example, the root item + * can provide a "childtype" node that specifies the type of the children. */ + +struct GdbMiRecursionContext { + GdbMiRecursionContext(int recursionLevelIn = 0) : + recursionLevel(recursionLevelIn), childNumChild(-1), childIndex(0) {} + + int recursionLevel; + int childNumChild; + int childIndex; + QString childType; + QString parentIName; +}; + +static void gbdMiToWatchData(const GdbMi &root, + const GdbMiRecursionContext &ctx, + QList<WatchData> *wl) { - const QByteArray valueBA(k, size); - switch (m_mode) { - case None: - case ChildModeStart: - return false; - case ExpectingIName: - m_result.iname = QString::fromLatin1(valueBA); - break; - case ExpectingAddress: { - const QString address = QString::fromLatin1(valueBA); - if (address.startsWith(QLatin1String("0x"))) { - m_result.address = address; - } else { - m_result.addressInfo = address; - } - } - break; - case ExpectingValue: - m_result.valueEncountered = true; - m_result.value = valueBA; - break; - case ExpectingValueEnabled: - m_result.valueEnabled = valueBA == "true"; - break; - case ExpectingValueEncoded: - m_result.valueEncoded = QString::fromLatin1(valueBA).toInt(); - break; - case ExpectingType: - m_result.type = QString::fromLatin1(valueBA); - break; - case ExpectingDisplayedType: - m_result.displayedType = QString::fromLatin1(valueBA); - break; - case ExpectingExtra: - m_result.extra = valueBA; - break; - case ExpectingInternal: - m_result.internal = valueBA == "true"; - break; - case ExpectingCommonChildType: - m_result.childType = QString::fromLatin1(valueBA); - break; - case ExpectingChildCount: - m_result.childCount = QString::fromLatin1(valueBA).toInt(); - break; - case ExpectingChildChildOverrideCount: - m_result.childChildCount = QString::fromLatin1(valueBA).toInt(); - break; - case ExpectingChildren: - case IgnoreNextChildMode: - case IgnoreNext: - break; - case ExpectingChildName: - m_result.children.back().name = QString::fromLatin1(valueBA); - break; - case ExpectingChildAddress: - m_result.children.back().address = QString::fromLatin1(valueBA); - break; - case ExpectingChildKeyEncoded: - m_result.children.back().keyEncoded = QString::fromLatin1(valueBA).toInt(); - break; - case ExpectingChildKey: - m_result.children.back().key = valueBA; - break; - case ExpectingChildValue: - m_result.children.back().valueEncountered = true; - m_result.children.back().value = valueBA; - break; - case ExpectingChildExpression: - m_result.children.back().exp = QString::fromLatin1(valueBA); - break; - case ExpectingChildValueEncoded: - m_result.children.back().valueEncoded = QString::fromLatin1(valueBA).toInt(); - break; - case ExpectingChildValueEnabled: - m_result.children.back().valueEnabled = valueBA == "true"; - break; - case ExpectingChildType: - m_result.children.back().type = QString::fromLatin1(valueBA); - break; - case ExpectingChildDisplayedType: - m_result.children.back().displayedType = QString::fromLatin1(valueBA); - break; - case ExpectingChildChildCount: - m_result.children.back().childCount = QString::fromLatin1(valueBA).toInt(); - break; + if (debug > 1) + qDebug() << Q_FUNC_INFO << '\n' << root.toString(false, 0); + WatchData w; + QString v; + // Check for name/iname and use as expression default + if (ctx.recursionLevel == 0) { + // parents have only iname, from which name is derived + if (!gdbMiGetStringValue(&w.iname, root, "iname")) + qWarning("Internal error: iname missing"); + w.name = w.iname; + const int lastDotPos = w.name.lastIndexOf(QLatin1Char('.')); + if (lastDotPos != -1) + w.name.remove(0, lastDotPos + 1); + w.exp = w.name; + } else { + // Children can have a 'name' attribute. If missing, assume array index + // For display purposes, it can be overridden by "key" + if (!gdbMiGetStringValue(&w.name, root, "name")) { + w.name = QString::number(ctx.childIndex); + } + // Set iname + w.iname = ctx.parentIName; + w.iname += QLatin1Char('.'); + w.iname += w.name; + // Key? + QString key; + if (gdbMiGetStringValue(&key, root, "key", "keyencoded")) { + w.name = key.size() > 13 ? key.mid(0, 13) + QLatin1String("...") : key; + } + } + if (w.name.isEmpty()) { + const QString msg = QString::fromLatin1("Internal error: Unable to determine name at level %1/%2 for %3").arg(ctx.recursionLevel).arg(w.iname, QLatin1String(root.toString(true, 2))); + qWarning("%s\n", qPrintable(msg)); + } + gdbMiGetStringValue(&w.displayedType, root, "displayedtype"); + if (gdbMiGetStringValue(&v, root, "editvalue")) + w.editvalue = v.toLatin1(); + if (gdbMiGetStringValue(&v, root, "exp")) + w.exp = v; + gdbMiGetStringValue(&w.addr, root, "addr"); + gdbMiGetStringValue(&w.saddr, root, "saddr"); + gdbMiGetBoolValue(&w.valueEnabled, root, "valueenabled"); + gdbMiGetBoolValue(&w.valueEditable, root, "valueeditable"); + if (gdbMiGetStringValue(&v, root, "valuetooltip", "valuetooltipencoded")) + w.setValue(v); + if (gdbMiGetStringValue(&v, root, "value", "valueencoded")) + w.setValue(v); + // Type from context or self + if (ctx.childType.isEmpty()) { + if (gdbMiGetStringValue(&v, root, "type")) + w.setType(v); + } else { + w.setType(ctx.childType); + } + // child count? + int numChild = -1; + if (ctx.childNumChild >= 0) { + numChild = ctx.childNumChild; + } else { + gdbMiGetIntValue(&numChild, root, "numchild"); + } + if (numChild >= 0) + w.setHasChildren(numChild > 0); + wl->push_back(w); + // Parse children with a new context + if (numChild == 0) + return; + const GdbMi childrenNode = root.findChild("children"); + if (!childrenNode.isValid()) + return; + const QList<GdbMi> children =childrenNode.children(); + if (children.empty()) + return; + wl->back().setChildrenUnneeded(); + GdbMiRecursionContext nextLevelContext(ctx.recursionLevel + 1); + nextLevelContext.parentIName = w.iname; + gdbMiGetStringValue(&nextLevelContext.childType, root, "childtype"); + if (!gdbMiGetIntValue(&nextLevelContext.childNumChild, root, "childnumchild")) + nextLevelContext.childNumChild = -1; + foreach(const GdbMi &child, children) { + gbdMiToWatchData(child, nextLevelContext, wl); + nextLevelContext.childIndex++; } - return true; } -bool QtDumperHelper::parseValue(const char *data, QtDumperResult *r) +bool QtDumperHelper::parseValue(const char *data, + QList<WatchData> *l) { - ValueDumperParser parser(data); - - if (!parser.run()) + l->clear(); + QByteArray fullData = data; + fullData.insert(0, '{'); + fullData.append(data); + fullData.append('}'); + GdbMi root(fullData); + if (!root.isValid()) return false; - *r = parser.result(); - // Sanity - if (!r->children.empty() && r->childCount != r->children.size()) - r->childCount = r->children.size(); - if (debug > 1) - qDebug() << '\n' << data << '\n' << *r; + gbdMiToWatchData(root, GdbMiRecursionContext(), l); return true; } diff --git a/src/plugins/debugger/watchutils.h b/src/plugins/debugger/watchutils.h index 395ba5f5eac9974abe2fa9694c0736752a2f0081..9c4280b0dfea7c6956e9c898ae6473dabea7f179 100644 --- a/src/plugins/debugger/watchutils.h +++ b/src/plugins/debugger/watchutils.h @@ -49,6 +49,7 @@ namespace Debugger { namespace Internal { class WatchData; +class GdbMi; QString dotEscape(QString str); QString currentTime(); @@ -89,49 +90,6 @@ QString cppExpressionAt(TextEditor::ITextEditor *editor, int pos, // Decode string data as returned by the dumper helpers. QString decodeData(const QByteArray &baIn, int encoding); -// Result of a dumper call. -struct QtDumperResult -{ - struct Child { - Child(); - - int keyEncoded; - int valueEncoded; - int childCount; - bool valueEnabled; - QString name; - QString address; - QString exp; - QString type; - QString displayedType; - QByteArray key; - bool valueEncountered; - QByteArray value; - }; - - QtDumperResult(); - void clear(); - QList<WatchData> toWatchData(int source = 0) const; - - QString iname; - QString address; - QString addressInfo; // "<synthetic>" or such, in the 2nd adress field. - QString type; - QString extra; - QString displayedType; - bool valueEncountered; - QByteArray value; - int valueEncoded; - bool valueEnabled; - int childCount; - bool internal; - QString childType; - int childChildCount; - QList <Child> children; -}; - -QDebug operator<<(QDebug in, const QtDumperResult &d); - /* Attempt to put common code of the dumper handling into a helper * class. * "Custom dumper" is a library compiled against the current @@ -181,7 +139,6 @@ public: void clear(); double dumperVersion() const { return m_dumperVersion; } - void setDumperVersion(double v) { m_dumperVersion = v; } int typeCount() const; // Look up a simple, non-template type @@ -192,17 +149,14 @@ public: int qtVersion() const; QString qtVersionString() const; - void setQtVersion(int v); - void setQtVersion(const QString &v); - QString qtNamespace() const; - void setQtNamespace(const QString &qtNamespace); // Complete parse of "query" (protocol 1) response from debuggee buffer. // 'data' excludes the leading indicator character. bool parseQuery(const char *data, Debugger debugger); - // Set up from pre-parsed type list - void parseQueryTypes(const QStringList &l, Debugger debugger); + bool parseQuery(const GdbMi &data, Debugger debugger); + // Sizes can be added as the debugger determines them + void addSize(const QString &name, int size); // Determine the parameters required for an "evaluate" (protocol 2) call void evaluationParameters(const WatchData &data, @@ -213,7 +167,7 @@ public: // Parse the value response (protocol 2) from debuggee buffer. // 'data' excludes the leading indicator character. - static bool parseValue(const char *data, QtDumperResult *r); + static bool parseValue(const char *data, QList<WatchData> *l); // What kind of debugger expressions are required to dump that type. // A debugger with restricted expression syntax can handle @@ -228,9 +182,6 @@ public: QString toString(bool debug = false) const; - // Helpers for debuggers that use a different dumper parser. - void addSize(const QString &name, int size); - void addExpression(const QString &expression, const QString &value); static QString msgDumperOutdated(double requiredVersion, double currentVersion); @@ -241,6 +192,7 @@ private: // Look up a simple (namespace) type static Type specialType(QString s); QString evaluationSizeofTypeExpression(const QString &typeName, Debugger d) const; + void parseQueryTypes(const QStringList &l, Debugger debugger); NameTypeMap m_nameTypeMap; SizeCache m_sizeCache; @@ -250,7 +202,9 @@ private: // They are not complete (std::allocator<X>). enum SpecialSizeType { IntSize, PointerSize, StdAllocatorSize, QSharedPointerSize, QSharedDataPointerSize, - QWeakPointerSize, QPointerSize, SpecialSizeCount }; + QWeakPointerSize, QPointerSize, + QListSize, QLinkedListSize, QVectorSize, QQueueSize, + SpecialSizeCount }; // Resolve name to enumeration or SpecialSizeCount (invalid) SpecialSizeType specialSizeType(const QString &t) const; @@ -268,6 +222,10 @@ private: QString m_qSharedPointerPrefix; QString m_qSharedDataPointerPrefix; QString m_qWeakPointerPrefix; + QString m_qListPrefix; + QString m_qLinkedListPrefix; + QString m_qVectorPrefix; + QString m_qQueuePrefix; }; QDebug operator<<(QDebug in, const QtDumperHelper::TypeData &d); diff --git a/src/plugins/projectexplorer/debugginghelper.cpp b/src/plugins/projectexplorer/debugginghelper.cpp index 6c39e7376d8acc829be26e7f1d69866087b868bf..61c5b4538d1a19a8b778a729afbfaa7bd4b48e22 100644 --- a/src/plugins/projectexplorer/debugginghelper.cpp +++ b/src/plugins/projectexplorer/debugginghelper.cpp @@ -106,7 +106,7 @@ QString DebuggingHelperLibrary::debuggingHelperLibraryByInstallData(const QStrin foreach(const QString &directory, debuggingHelperLibraryDirectories(qtInstallData)) { const QFileInfo fi(helperFilePath(directory)); - if (fi.exists() && fi.lastModified() > lastModified) + if (fi.exists() && fi.lastModified() >= lastModified) return fi.filePath(); } return QString(); diff --git a/src/plugins/projectexplorer/outputwindow.cpp b/src/plugins/projectexplorer/outputwindow.cpp index d886584db077bc463a39043b3b7a39ed5d552114..d2f7ec7ac2793a14b0b3c96cc0f277dd9aefaf0d 100644 --- a/src/plugins/projectexplorer/outputwindow.cpp +++ b/src/plugins/projectexplorer/outputwindow.cpp @@ -341,6 +341,7 @@ OutputWindow::OutputWindow(QWidget *parent) : QPlainTextEdit(parent) { m_enforceNewline = false; + m_scrollToBottom = false; setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn); //setCenterOnScroll(false); @@ -392,8 +393,18 @@ OutputWindow::~OutputWindow() Core::ICore::instance()->removeContextObject(m_outputWindowContext); } +void OutputWindow::showEvent(QShowEvent *e) +{ + QPlainTextEdit::showEvent(e); + if (m_scrollToBottom) { + verticalScrollBar()->setValue(verticalScrollBar()->maximum()); + } + m_scrollToBottom = false; +} + void OutputWindow::appendOutput(const QString &out) { + m_scrollToBottom = true; QString s = out; m_enforceNewline = true; // make appendOutputInline put in a newline next time if (s.endsWith(QLatin1Char('\n'))) { @@ -407,6 +418,7 @@ void OutputWindow::appendOutput(const QString &out) void OutputWindow::appendOutputInline(const QString &out) { + m_scrollToBottom = true; setMaximumBlockCount(MaxBlockCount); int newline = -1; @@ -439,6 +451,7 @@ void OutputWindow::appendOutputInline(const QString &out) void OutputWindow::insertLine() { + m_scrollToBottom = true; setMaximumBlockCount(MaxBlockCount); appendPlainText(QString()); enableUndoRedo(); diff --git a/src/plugins/projectexplorer/outputwindow.h b/src/plugins/projectexplorer/outputwindow.h index 6820f5076e012f368f2e25c211fbb1de09a95316..ce81025bdbda87623d56710547b88eb979307213 100644 --- a/src/plugins/projectexplorer/outputwindow.h +++ b/src/plugins/projectexplorer/outputwindow.h @@ -126,10 +126,13 @@ public: void appendOutputInline(const QString &out); void insertLine(); + void showEvent(QShowEvent *); + private: Core::BaseContext *m_outputWindowContext; void enableUndoRedo(); bool m_enforceNewline; + bool m_scrollToBottom; }; #if 0 diff --git a/src/plugins/projectexplorer/toolchain.cpp b/src/plugins/projectexplorer/toolchain.cpp index f8fba415b429fea98cd61a9a9321394a979a5af8..b256b5e3ed147df3cbef0828f355440183d95a2e 100644 --- a/src/plugins/projectexplorer/toolchain.cpp +++ b/src/plugins/projectexplorer/toolchain.cpp @@ -367,8 +367,7 @@ QByteArray MSVCToolChain::predefinedMacros() QByteArray key = split.at(0).mid(1); QByteArray value = split.at(1); if (!value.isEmpty()) { - value = value.mid(1); - value.chop(1); + value.chop(1); //remove '\n' } QByteArray newDefine = "#define " + key + " " + value + '\n'; m_predefinedMacros.append(newDefine); diff --git a/src/plugins/qt4projectmanager/qt-s60/qt-s60.pri b/src/plugins/qt4projectmanager/qt-s60/qt-s60.pri index 279447ce4b7c0b7e3a52b1294779c40e6ba3e48e..d421fe16c2933a1d8930a3b10b4f03ff8e291d48 100644 --- a/src/plugins/qt4projectmanager/qt-s60/qt-s60.pri +++ b/src/plugins/qt4projectmanager/qt-s60/qt-s60.pri @@ -22,5 +22,5 @@ SUPPORT_QT_S60 = $$(QTCREATOR_WITH_S60) $$PWD/rvcttoolchain.h FORMS += $$PWD/s60devicespreferencepane.ui OTHER_FILES += $$PWD/qt-s60-todo.txt - include(../../shared/trk/trk.pri)||error("could not include trk.pri") + include(../../../shared/trk/trk.pri)||error("could not include trk.pri") } diff --git a/src/plugins/qtscripteditor/parser/javascript.g b/src/plugins/qtscripteditor/parser/javascript.g index ceb2aeb726b247a5f2fd8496fc23d3dd7cd3cfad..e75ee1cf7ed99624899e74dcaf7456e72a323d9a 100644 --- a/src/plugins/qtscripteditor/parser/javascript.g +++ b/src/plugins/qtscripteditor/parser/javascript.g @@ -2118,7 +2118,7 @@ PropertyNameAndValueListOpt: PropertyNameAndValueList ; token_buffer[1].dval = yylval = lexer->dval(); token_buffer[1].loc = yylloc = location(lexer); - if (t_action(errorState, yytoken)) { + if (token_buffer[0].token != -1 && t_action(errorState, yytoken)) { QString msg = QString::fromUtf8("Removed token"); if (const char *tokenSpell = spell[token_buffer[0].token]) { msg += QLatin1String(": `"); diff --git a/src/shared/trk/launcher.cpp b/src/shared/trk/launcher.cpp index 5535cb1a62e6e777128589289fe745075b496dd1..a984cee40d5fd4b9e9e00b8983e96adfa6cdd832 100644 --- a/src/shared/trk/launcher.cpp +++ b/src/shared/trk/launcher.cpp @@ -397,13 +397,14 @@ void Launcher::handleWaitForFinished(const TrkResult &result) void Launcher::handleSupportMask(const TrkResult &result) { - const char *data = result.data.data(); + const char *data = result.data.data() + 1; + QByteArray str; for (int i = 0; i < 32; ++i) { //str.append(" [" + formatByte(data[i]) + "]: "); for (int j = 0; j < 8; ++j) if (data[i] & (1 << j)) - str.append(QByteArray::number(i * 8 + j, 16)); + str.append(QByteArray::number(i * 8 + j, 16) + " "); } logMessage("SUPPORTED: " + str); } diff --git a/tests/auto/aggregation/aggregation.pro b/tests/auto/aggregation/aggregation.pro index c35c696239ebacaa8042ba1f3f5d45dd32e96d28..ca1d1205a35ac31fa43968e3a987bd141519f4e9 100644 --- a/tests/auto/aggregation/aggregation.pro +++ b/tests/auto/aggregation/aggregation.pro @@ -12,3 +12,4 @@ SOURCES += tst_aggregate.cpp \ HEADERS += $$AGGREGATION_PATH/aggregate.h \ $$AGGREGATION_PATH/aggregation_global.h +TARGET=tst_$$TARGET diff --git a/tests/auto/auto.pro b/tests/auto/auto.pro index 826e842ef9c64279563d9bd0e174e3c7178e1733..193c1156ecb46e4197f8154f418e6b1d6eab36f7 100644 --- a/tests/auto/auto.pro +++ b/tests/auto/auto.pro @@ -3,7 +3,6 @@ TEMPLATE = subdirs SUBDIRS += \ cplusplus \ debugger \ - extensionsystem \ fakevim \ # profilereader \ aggregation diff --git a/tests/auto/cplusplus/ast/ast.pro b/tests/auto/cplusplus/ast/ast.pro index 84733f97e6f78c44972ef40bf488f2da594ce7fc..2f5a0a33eae956f43a47ec9758b53513ae8cbce9 100644 --- a/tests/auto/cplusplus/ast/ast.pro +++ b/tests/auto/cplusplus/ast/ast.pro @@ -3,3 +3,5 @@ CONFIG += qt warn_on console depend_includepath QT = core testlib include(../shared/shared.pri) SOURCES += tst_ast.cpp +TARGET=tst_$$TARGET + diff --git a/tests/auto/cplusplus/lookup/lookup.pro b/tests/auto/cplusplus/lookup/lookup.pro index cd02b709575605ebe5d0e25a538441a18f950f21..b80aa2f2b7bc30a046f5ecb7bbcc89f1f8f983d1 100644 --- a/tests/auto/cplusplus/lookup/lookup.pro +++ b/tests/auto/cplusplus/lookup/lookup.pro @@ -5,3 +5,4 @@ QT = core testlib include(../../../../src/libs/cplusplus/cplusplus-lib.pri) SOURCES += tst_lookup.cpp +TARGET=tst_$$TARGET diff --git a/tests/auto/cplusplus/semantic/semantic.pro b/tests/auto/cplusplus/semantic/semantic.pro index 37c013685f73f42c40149e298869ce9563779e7b..09f80ab27abb71ce1efd01a76ff1ca105b1c5cc1 100644 --- a/tests/auto/cplusplus/semantic/semantic.pro +++ b/tests/auto/cplusplus/semantic/semantic.pro @@ -4,3 +4,4 @@ QT = core testlib include(../shared/shared.pri) SOURCES += tst_semantic.cpp +TARGET=tst_$$TARGET diff --git a/tests/auto/debugger/dumpers.pro b/tests/auto/debugger/dumpers.pro index ca5338af380152da1e950c5fa0055464cc6cdc64..201c36cb436661b3c2d92aaafed17eeced9efe4b 100644 --- a/tests/auto/debugger/dumpers.pro +++ b/tests/auto/debugger/dumpers.pro @@ -14,3 +14,5 @@ DEFINES += MACROSDEBUG INCLUDEPATH += $$DEBUGGERDIR $$UTILSDIR $$MACROSDIR +TARGET = tst_$$TARGET + diff --git a/tests/auto/debugger/plugin.pro b/tests/auto/debugger/plugin.pro index fae675b38f82ec2b22103996687202db00e328a0..7cc42dac75082c2cf96e852fdef06612beae565f 100644 --- a/tests/auto/debugger/plugin.pro +++ b/tests/auto/debugger/plugin.pro @@ -12,3 +12,5 @@ DEFINES += MACROSDEBUG INCLUDEPATH += $$DEBUGGERDIR $$UTILSDIR $$MACROSDIR +TARGET = tst_$$TARGET + diff --git a/tests/auto/debugger/tst_dumpers.cpp b/tests/auto/debugger/tst_dumpers.cpp index d7d3945212364f6ed9948bc58a77d953da9b213e..3f84e5cb6feee817a81da4b1bd036278fb50d604 100644 --- a/tests/auto/debugger/tst_dumpers.cpp +++ b/tests/auto/debugger/tst_dumpers.cpp @@ -1501,7 +1501,7 @@ template <typename K, typename V> append(" isSimpleValue: ").append(N(simpleVal)). append(" keyOffset: ").append(N(transKeyOffset)).append(" valueOffset: "). append(N(transValOffset)).append(" mapnodesize: "). - append(N(nodeSize)).append("',children=["); + append(N(qulonglong(nodeSize))).append("',children=["); // 64bit Linux hack typedef typename QMap<K, V>::iterator mapIter; for (mapIter it = map.begin(); it != map.end(); ++it) { if (it != map.begin()) @@ -2368,7 +2368,9 @@ void tst_Debugger::initTestCase() d.weakref = d.strongref = 0; // That's what the destructor expects. QVERIFY(sizeof(int) == sizeof(d.weakref)); QVERIFY(sizeof(int) == sizeof(d.strongref)); - QVERIFY(sizeof(QObjectPrivate) == sizeof(ObjectPrivate)); + const size_t qObjectPrivateSize = sizeof(QObjectPrivate); + const size_t objectPrivateSize = sizeof(ObjectPrivate); + QVERIFY2(qObjectPrivateSize == objectPrivateSize, QString::fromLatin1("QObjectPrivate=%1 ObjectPrivate=%2").arg(qObjectPrivateSize).arg(objectPrivateSize).toLatin1().constData()); VERIFY_OFFSETOF(threadData); VERIFY_OFFSETOF(extraData); VERIFY_OFFSETOF(objectName); @@ -2379,11 +2381,12 @@ void tst_Debugger::initTestCase() VERIFY_OFFSETOF(currentChildBeingDeleted); VERIFY_OFFSETOF(connectedSignals); VERIFY_OFFSETOF(deleteWatch); +#ifdef QT3_SUPPORT #if QT_VERSION < 0x040600 VERIFY_OFFSETOF(pendingChildInsertedEvents); -#else - VERIFY_OFFSETOF(declarativeData); - VERIFY_OFFSETOF(objectGuards); +#endif +#endif +#if QT_VERSION >= 0x040600 VERIFY_OFFSETOF(sharedRefcount); #endif } diff --git a/tests/auto/fakevim/fakevim.pro b/tests/auto/fakevim/fakevim.pro index 04fefc12d30548202540f2b9cf6dea67a3d89d80..a4aaea078ed29b2f350d81243cd758280ab2f397 100644 --- a/tests/auto/fakevim/fakevim.pro +++ b/tests/auto/fakevim/fakevim.pro @@ -21,3 +21,4 @@ HEADERS += \ INCLUDEPATH += $$FAKEVIMDIR $$UTILSDIR +TARGET=tst_$$TARGET diff --git a/tests/auto/profilereader/profilereader.pro b/tests/auto/profilereader/profilereader.pro index b80ce8e49541443eb6f9ca1b345c671f7e9cb9bd..486ddd547d056590f081414d24770779567b04b2 100644 --- a/tests/auto/profilereader/profilereader.pro +++ b/tests/auto/profilereader/profilereader.pro @@ -14,3 +14,4 @@ HEADERS += \ profilereader.h \ profilecache.h \ qtversionmanager.h +TARGET=tst_$$TARGET