Commit 4cbbe366 authored by hjk's avatar hjk

debugger: make a 'type' a QByteArray, not a QString

Saves lots of conversion.
parent d875ad4e
......@@ -683,7 +683,7 @@ void CdbEngine::evaluateWatcher(WatchData *wd)
exp.remove(0, 6);
if (m_d->evaluateExpression(exp, &value, &type, &errorMessage)) {
wd->setValue(value);
wd->setType(type);
wd->setType(type.toUtf8());
} else {
wd->setValue(errorMessage);
wd->setTypeUnneeded();
......
......@@ -343,14 +343,14 @@ CdbSymbolGroupContext *CdbSymbolGroupContext::create(const QString &prefix,
// Fix display values: Pass through strings, convert unsigned integers
// to decimal ('0x5454`fedf'), remove inner templates from
// "0x4343 class list<>".
static inline QString fixValue(const QString &value, const QString &type)
static inline QString fixValue(const QString &value, const QLatin1String &type)
{
// Pass through strings
if (value.endsWith(QLatin1Char('"')))
return value;
const int size = value.size();
// Real Integer numbers Unsigned hex numbers (0x)/decimal numbers (0n)
if (type != QLatin1String("bool") && isIntType(type)) {
if (type != "bool" && isIntType(type)) {
const QVariant intValue = CdbCore::SymbolGroupContext::getIntValue(value);
if (intValue.isValid())
return intValue.toString();
......
......@@ -165,7 +165,7 @@ public:
virtual unsigned debuggerCapabilities() const { return 0; }
virtual bool isSynchronous() const { return false; }
virtual QString qtNamespace() const { return QString(); }
virtual QByteArray qtNamespace() const { return QByteArray(); }
virtual void createSnapshot() {}
virtual void updateAll() {}
......
......@@ -134,7 +134,7 @@ static inline QString msgRetrievingWatchData(int pending)
void GdbEngine::runDirectDebuggingHelperClassic(const WatchData &data, bool dumpChildren)
{
Q_UNUSED(dumpChildren)
QByteArray type = data.type.toLatin1();
QByteArray type = data.type;
QByteArray cmd;
if (type == "QString" || type.endsWith("::QString"))
......@@ -172,7 +172,7 @@ void GdbEngine::runDebuggingHelperClassic(const WatchData &data0, bool dumpChild
m_processedNames.insert(processedName);
QByteArray params;
QStringList extraArgs;
QList<QByteArray> extraArgs;
const QtDumperHelper::TypeData td = m_dumperHelper.typeData(data0.type);
m_dumperHelper.evaluationParameters(data, td, QtDumperHelper::GdbDebugger, &params, &extraArgs);
......@@ -185,18 +185,23 @@ void GdbEngine::runDebuggingHelperClassic(const WatchData &data0, bool dumpChild
if (data.addr.startsWith("0x"))
addr = "(void*)" + data.addr;
else if (data.exp.isEmpty()) // happens e.g. for QAbstractItem
addr = QByteArray (1, '0');
addr = QByteArray(1, '0');
else
addr = "&(" + data.exp + ')';
sendWatchParameters(params);
QString cmd;
QTextStream(&cmd) << "call " << "(void*)qDumpObjectData440(" <<
protocol << ",0," << addr << ',' << (dumpChildren ? '1' : '0')
<< ',' << extraArgs.join(QString(_c(','))) << ')';
QByteArray cmd = "call (void*)qDumpObjectData440("
+ QByteArray::number(protocol)
+ ",0,"
+ addr
+ ','
+ (dumpChildren ? '1' : '0');
foreach (const QByteArray &ex, extraArgs)
cmd + ',' + ex;
cmd += ')';
postCommand(cmd.toLatin1(), WatchUpdate | NonCriticalResponse);
postCommand(cmd, WatchUpdate | NonCriticalResponse);
showStatusMessage(msgRetrievingWatchData(m_pendingWatchRequests + 1), 10000);
......@@ -269,7 +274,7 @@ void GdbEngine::updateSubItemClassic(const WatchData &data0)
if (theDebuggerBoolSetting(AutoDerefPointers)) {
// Try automatic dereferentiation
data.exp = "(*(" + data.exp + "))";
data.type = data.type + _("."); // FIXME: fragile HACK to avoid recursion
data.type = data.type + "."; // FIXME: fragile HACK to avoid recursion
insertData(data);
} else {
data.setChildrenUnneeded();
......@@ -439,8 +444,8 @@ void GdbEngine::handleDebuggingHelperValue3Classic(const GdbResponse &response)
data.setError(WatchData::msgNotInScope());
data.setAllUnneeded();
insertData(data);
} else if (data.type == __("QString")
|| data.type.endsWith(__("::QString"))) {
} else if (data.type == "QString"
|| data.type.endsWith("::QString")) {
QList<QByteArray> list = out.split(' ');
QString str;
int l = out.isEmpty() ? 0 : list.size();
......@@ -450,8 +455,8 @@ void GdbEngine::handleDebuggingHelperValue3Classic(const GdbResponse &response)
data.setHasChildren(false);
data.setAllUnneeded();
insertData(data);
} else if (data.type == __("QStringList")
|| data.type.endsWith(__("::QStringList"))) {
} else if (data.type == "QStringList"
|| data.type.endsWith("::QStringList")) {
if (out.isEmpty()) {
data.setValue(tr("<0 items>"));
data.setHasChildren(false);
......@@ -731,7 +736,7 @@ void GdbEngine::handleQueryDebuggingHelperClassic(const GdbResponse &response)
showStatusMessage(successMsg);
// Sanity check for Qt version of dumpers and debuggee.
QByteArray ns = m_dumperHelper.qtNamespace().toLatin1();
QByteArray ns = m_dumperHelper.qtNamespace();
postCommand("-var-create A@ * '" + ns + "qVersion'()",
CB(handleDebuggingHelperVersionCheckClassic));
postCommand("-var-delete A@");
......@@ -855,7 +860,7 @@ void GdbEngine::handleVarListChildrenHelperClassic(const GdbMi &item,
data.exp = parent.exp;
data.name = tr("<n/a>");
data.iname = parent.iname + ".@";
data.type = tr("<anonymous union>");
data.type = tr("<anonymous union>").toUtf8();
} else {
// A structure. Hope there's nothing else...
data.exp = '(' + parent.exp + ")." + data.name.toLatin1();
......
......@@ -3267,15 +3267,15 @@ void GdbEngine::setAutoDerefPointers(const QVariant &on)
updateLocals();
}
bool GdbEngine::hasDebuggingHelperForType(const QString &type) const
bool GdbEngine::hasDebuggingHelperForType(const QByteArray &type) const
{
if (!theDebuggerBoolSetting(UseDebuggingHelpers))
return false;
if (m_gdbAdapter->dumperHandling() == AbstractGdbAdapter::DumperNotAvailable) {
// "call" is not possible in gdb when looking at core files
return type == __("QString") || type.endsWith(__("::QString"))
|| type == __("QStringList") || type.endsWith(__("::QStringList"));
return type == "QString" || type.endsWith("::QString")
|| type == "QStringList" || type.endsWith("::QStringList");
}
if (theDebuggerBoolSetting(DebugDebuggingHelpers)
......@@ -3429,7 +3429,7 @@ void GdbEngine::handleVarCreate(const GdbResponse &response)
data.setError(QString::fromLocal8Bit(response.data.findChild("msg").data()));
if (data.isWatcher()) {
data.value = WatchData::msgNotInScope();
data.type = _(" ");
data.type = " ";
data.setAllUnneeded();
data.setHasChildren(false);
data.valueEnabled = false;
......@@ -3496,7 +3496,7 @@ WatchData GdbEngine::localVariable(const GdbMi &item,
//: Type of local variable or parameter shadowed by another
//: variable of the same name in a nested block.
setWatchDataValue(data, item);
data.setType(GdbEngine::tr("<shadowed>"));
data.setType(GdbEngine::tr("<shadowed>").toUtf8());
data.setHasChildren(false);
return data;
}
......@@ -3576,9 +3576,9 @@ void GdbEngine::handleWatchPoint(const GdbResponse &response)
QString str = _(parsePlainConsoleStream(response));
// "(void *) 0xbfa7ebfc"
QString addr = str.mid(9);
QString ns = m_dumperHelper.qtNamespace();
QString type = ns.isEmpty() ? _("QWidget*") : _("'%1QWidget'*").arg(ns);
QString exp = _("(*(%1)%2)").arg(type).arg(addr);
QByteArray ns = m_dumperHelper.qtNamespace();
QByteArray type = ns.isEmpty() ? "QWidget*" : ("'" + ns + "QWidget'*");
QString exp = _("(*(%1)%2)").arg(_(type)).arg(addr);
watchHandler()->watchExpression(exp);
}
}
......
......@@ -116,7 +116,7 @@ private: ////////// General Interface //////////
virtual void notifyInferiorSetupFailed();
virtual void executeDebuggerCommand(const QString &command);
virtual QString qtNamespace() const { return m_dumperHelper.qtNamespace(); }
virtual QByteArray qtNamespace() const { return m_dumperHelper.qtNamespace(); }
private: ////////// General State //////////
......@@ -471,7 +471,7 @@ private: ////////// View & Data Stuff //////////
void runDebuggingHelperClassic(const WatchData &data, bool dumpChildren);
void runDirectDebuggingHelperClassic(const WatchData &data, bool dumpChildren);
bool hasDebuggingHelperForType(const QString &type) const;
bool hasDebuggingHelperForType(const QByteArray &type) const;
void handleVarListChildrenClassic(const GdbResponse &response);
void handleVarListChildrenHelperClassic(const GdbMi &child,
......
......@@ -180,7 +180,7 @@ bool QmlCppEngine::isSynchronous() const
return m_activeEngine->isSynchronous();
}
QString QmlCppEngine::qtNamespace() const
QByteArray QmlCppEngine::qtNamespace() const
{
return m_cppEngine->qtNamespace();
}
......
......@@ -46,7 +46,7 @@ public:
virtual unsigned debuggerCapabilities() const;
virtual bool isSynchronous() const;
virtual QString qtNamespace() const;
virtual QByteArray qtNamespace() const;
virtual void createSnapshot();
virtual void updateAll();
......
......@@ -88,7 +88,7 @@ QDataStream& operator>>(QDataStream& s, WatchData &data)
QString type;
bool hasChildren;
s >> data.exp >> data.name >> value >> type >> hasChildren >> data.objectId;
data.setType(type, false);
data.setType(type.toUtf8(), false);
data.setValue(value);
data.setHasChildren(hasChildren);
data.setAllUnneeded();
......
......@@ -746,55 +746,55 @@ void ScriptEngine::updateSubItem(const WatchData &data0)
if (data.isTypeNeeded() || data.isValueNeeded()) {
const QScriptValue &ob = data.scriptValue;
if (ob.isArray()) {
data.setType(QLatin1String("Array"), false);
data.setType("Array", false);
data.setValue(QString(QLatin1Char(' ')));
} else if (ob.isBool()) {
data.setType(QLatin1String("Bool"), false);
data.setType("Bool", false);
data.setValue(ob.toBool() ? QLatin1String("true") : QLatin1String("false"));
data.setHasChildren(false);
} else if (ob.isDate()) {
data.setType(QLatin1String("Date"), false);
data.setType("Date", false);
data.setValue(ob.toDateTime().toString());
data.setHasChildren(false);
} else if (ob.isError()) {
data.setType(QLatin1String("Error"), false);
data.setType("Error", false);
data.setValue(QString(QLatin1Char(' ')));
} else if (ob.isFunction()) {
data.setType(QLatin1String("Function"), false);
data.setType("Function", false);
data.setValue(QString(QLatin1Char(' ')));
} else if (ob.isNull()) {
const QString nullValue = QLatin1String("<null>");
data.setType(nullValue, false);
data.setType("<null>", false);
data.setValue(nullValue);
} else if (ob.isNumber()) {
data.setType(QLatin1String("Number"), false);
data.setType("Number", false);
data.setValue(QString::number(ob.toNumber()));
data.setHasChildren(false);
} else if (ob.isObject()) {
data.setType(QLatin1String("Object"), false);
data.setType("Object", false);
data.setValue(QString(QLatin1Char(' ')));
} else if (ob.isQMetaObject()) {
data.setType(QLatin1String("QMetaObject"), false);
data.setType("QMetaObject", false);
data.setValue(QString(QLatin1Char(' ')));
} else if (ob.isQObject()) {
data.setType(QLatin1String("QObject"), false);
data.setType("QObject", false);
data.setValue(QString(QLatin1Char(' ')));
} else if (ob.isRegExp()) {
data.setType(QLatin1String("RegExp"), false);
data.setType("RegExp", false);
data.setValue(ob.toRegExp().pattern());
} else if (ob.isString()) {
data.setType(QLatin1String("String"), false);
data.setType("String", false);
data.setValue(ob.toString());
} else if (ob.isVariant()) {
data.setType(QLatin1String("Variant"), false);
data.setType("Variant", false);
data.setValue(QString(QLatin1Char(' ')));
} else if (ob.isUndefined()) {
data.setType(QLatin1String("<undefined>"), false);
data.setType("<undefined>", false);
data.setValue(QLatin1String("<unknown>"));
data.setHasChildren(false);
} else {
const QString unknown = QLatin1String("<unknown>");
data.setType(unknown, false);
data.setType("<unknown>", false);
data.setValue(unknown);
data.setHasChildren(false);
}
......
......@@ -68,7 +68,7 @@ void WatchData::setValue(const QString &value0)
hasChildren = true; // at least one...
}
// strip off quoted characters for chars.
if (value.endsWith(QLatin1Char('\'')) && type.endsWith(QLatin1String("char"))) {
if (value.endsWith(QLatin1Char('\'')) && type.endsWith("char")) {
const int blankPos = value.indexOf(QLatin1Char(' '));
if (blankPos != -1)
value.truncate(blankPos);
......@@ -105,26 +105,26 @@ void WatchData::setValueToolTip(const QString &tooltip)
valuetooltip = tooltip;
}
void WatchData::setType(const QString &str, bool guessChildrenFromType)
void WatchData::setType(const QByteArray &str, bool guessChildrenFromType)
{
type = str.trimmed();
bool changed = true;
while (changed) {
if (type.endsWith(QLatin1String("const")))
if (type.endsWith("const"))
type.chop(5);
else if (type.endsWith(QLatin1Char(' ')))
else if (type.endsWith(' '))
type.chop(1);
else if (type.endsWith(QLatin1Char('&')))
else if (type.endsWith('&'))
type.chop(1);
else if (type.startsWith(QLatin1String("const ")))
else if (type.startsWith("const "))
type = type.mid(6);
else if (type.startsWith(QLatin1String("volatile ")))
else if (type.startsWith("volatile "))
type = type.mid(9);
else if (type.startsWith(QLatin1String("class ")))
else if (type.startsWith("class "))
type = type.mid(6);
else if (type.startsWith(QLatin1String("struct ")))
else if (type.startsWith("struct "))
type = type.mid(6);
else if (type.startsWith(QLatin1Char(' ')))
else if (type.startsWith(' '))
type = type.mid(1);
else
changed = false;
......
......@@ -63,7 +63,7 @@ public:
};
void setValue(const QString &);
void setType(const QString &, bool guessChildrenFromType = true);
void setType(const QByteArray &, bool guessChildrenFromType = true);
void setValueToolTip(const QString &);
void setError(const QString &);
void setAddress(const QByteArray &);
......@@ -116,7 +116,7 @@ public:
int editformat; // Format of displayed value
QString valuetooltip; // Tooltip in value column
QString typeFormats; // Selection of formats of displayed value
QString type; // Type for further processing
QByteArray type; // Type for further processing
QString displayedType;// Displayed type (optional)
QByteArray variable; // Name of internal Gdb variable if created
QByteArray addr; // Displayed address
......
......@@ -435,7 +435,7 @@ static inline QString formattedValue(const WatchData &data, int format)
if (!firstChar.isDigit() && firstChar != QLatin1Char('-'))
return data.value;
// Append quoted, printable character also for decimal.
if (data.type.endsWith(QLatin1String("char"))) {
if (data.type.endsWith("char")) {
bool ok;
const int code = data.value.toInt(&ok);
return ok ? reformatCharacter(code, format) : data.value;
......@@ -444,7 +444,7 @@ static inline QString formattedValue(const WatchData &data, int format)
if (format <= 0)
return data.value;
// Evil hack, covers 'unsigned' as well as quint64.
if (data.type.contains(QLatin1Char('u')))
if (data.type.contains('u'))
return reformatInteger(data.value.toULongLong(), format);
return reformatInteger(data.value.toLongLong(), format);
}
......@@ -653,7 +653,7 @@ QVariant WatchModel::data(const QModelIndex &idx, int role) const
bool ok;
const quint64 addr = data.addr.toULongLong(&ok, 16);
if (ok && addr)
return QString("*(%1*)%2").arg(data.type).arg(addr);
return QString("*(%1*)%2").arg(QLatin1String(data.type)).arg(addr);
}
WatchItem *parent = item->parent;
if (parent && !parent->exp.isEmpty())
......@@ -669,10 +669,10 @@ QVariant WatchModel::data(const QModelIndex &idx, int role) const
return m_handler->m_expandedINames.contains(data.iname);
case LocalsTypeFormatListRole: {
if (isIntType(data.type) && data.type != QLatin1String("bool"))
if (isIntType(data.type) && data.type != "bool")
return QStringList() << tr("decimal") << tr("hexadecimal")
<< tr("binary") << tr("octal");
if (data.type.endsWith(QLatin1Char('*')))
if (data.type.endsWith('*'))
return QStringList()
<< tr("Raw pointer")
<< tr("Latin1 string")
......
This diff is collapsed.
......@@ -70,19 +70,19 @@ inline bool isNameChar(char c)
bool hasLetterOrNumber(const QString &exp);
bool hasSideEffects(const QString &exp);
bool isKeyWord(const QString &exp);
bool isPointerType(const QString &type);
bool isCharPointerType(const QString &type);
bool isPointerType(const QByteArray &type);
bool isCharPointerType(const QByteArray &type);
bool startsWithDigit(const QString &str);
QString stripPointerType(QString type);
QByteArray stripPointerType(QByteArray type);
QString gdbQuoteTypes(const QString &type);
bool extractTemplate(const QString &type, QString *tmplate, QString *inner);
QString extractTypeFromPTypeOutput(const QString &str);
bool isIntOrFloatType(const QString &type);
bool isIntType(const QString &type);
bool isSymbianIntType(const QString &type);
bool isIntOrFloatType(const QByteArray &type);
bool isIntType(const QByteArray &type);
bool isSymbianIntType(const QByteArray &type);
enum GuessChildrenResult { HasChildren, HasNoChildren, HasPossiblyChildren };
GuessChildrenResult guessChildren(const QString &type);
GuessChildrenResult guessChildren(const QByteArray &type);
QString quoteUnprintableLatin1(const QByteArray &ba);
......@@ -144,8 +144,8 @@ public:
Type type;
bool isTemplate;
QString tmplate;
QString inner;
QByteArray tmplate;
QByteArray inner;
};
QtDumperHelper();
......@@ -155,28 +155,28 @@ public:
int typeCount() const;
// Look up a simple, non-template type
Type simpleType(const QString &simpleType) const;
Type simpleType(const QByteArray &simpleType) const;
// Look up a (potentially) template type and fill parameter struct
TypeData typeData(const QString &typeName) const;
Type type(const QString &typeName) const;
TypeData typeData(const QByteArray &typeName) const;
Type type(const QByteArray &typeName) const;
int qtVersion() const;
QString qtVersionString() const;
QString qtNamespace() const;
QByteArray qtVersionString() const;
QByteArray qtNamespace() const;
// Complete parse of "query" (protocol 1) response from debuggee buffer.
// 'data' excludes the leading indicator character.
bool parseQuery(const char *data);
bool parseQuery(const GdbMi &data);
// Sizes can be added as the debugger determines them
void addSize(const QString &name, int size);
void addSize(const QByteArray &type, int size);
// Determine the parameters required for an "evaluate" (protocol 2) call
void evaluationParameters(const WatchData &data,
const TypeData &td,
Debugger debugger,
QByteArray *inBuffer,
QStringList *extraParameters) const;
QList<QByteArray> *extraParameters) const;
// Parse the value response (protocol 2) from debuggee buffer.
// 'data' excludes the leading indicator character.
......@@ -188,15 +188,15 @@ public:
private:
typedef QMap<QString, Type> NameTypeMap;
typedef QMap<QString, int> SizeCache;
typedef QMap<QByteArray, int> SizeCache;
// Look up a simple (namespace) type
QString evaluationSizeofTypeExpression(const QString &typeName, Debugger d) const;
QString qMapNodeValueOffsetExpression(const QString &type,
const QString &addressIn,
Debugger debugger) const;
QByteArray evaluationSizeofTypeExpression(const QByteArray &typeName, Debugger d) const;
QByteArray qMapNodeValueOffsetExpression(const QByteArray &type,
const QByteArray &addressIn, Debugger debugger) const;
QString lookupCdbDummyAddressExpression(const QString &expr, const QString &address) const;
QByteArray lookupCdbDummyAddressExpression
(const QByteArray &expr, const QByteArray &address) const;
NameTypeMap m_nameTypeMap;
SizeCache m_sizeCache;
......@@ -211,25 +211,26 @@ private:
SpecialSizeCount };
// Resolve name to enumeration or SpecialSizeCount (invalid)
SpecialSizeType specialSizeType(const QString &t) const;
SpecialSizeType specialSizeType(const QByteArray &type) const;
int m_specialSizes[SpecialSizeCount];
QMap<QString, QString> m_expressionCache;
typedef QMap<QByteArray, QByteArray> ExpressionCache;
ExpressionCache m_expressionCache;
int m_qtVersion;
double m_dumperVersion;
QString m_qtNamespace;
void setQClassPrefixes(const QString &qNamespace);
QString m_qPointerPrefix;
QString m_qSharedPointerPrefix;
QString m_qSharedDataPointerPrefix;
QString m_qWeakPointerPrefix;
QString m_qListPrefix;
QString m_qLinkedListPrefix;
QString m_qVectorPrefix;
QString m_qQueuePrefix;
QByteArray m_qtNamespace;
void setQClassPrefixes(const QByteArray &qNamespace);
QByteArray m_qPointerPrefix;
QByteArray m_qSharedPointerPrefix;
QByteArray m_qSharedDataPointerPrefix;
QByteArray m_qWeakPointerPrefix;
QByteArray m_qListPrefix;
QByteArray m_qLinkedListPrefix;
QByteArray m_qVectorPrefix;
QByteArray m_qQueuePrefix;
};
QDebug operator<<(QDebug in, const QtDumperHelper::TypeData &d);
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment