From 076488bfbb80142ce014fffc8d65db05b4e2818a Mon Sep 17 00:00:00 2001
From: hjk <qtc-committer@nokia.com>
Date: Wed, 21 Jan 2009 11:12:12 +0100
Subject: [PATCH] Use gdb's 'print' command to access dumper output.

Simple solution after all. This idea got initially dropped early in the
process because it does not handle binary data and using x/x was
way to slow. But since we use only printable characters now thanks
to base64 encoding etc using 'p' becomes feasible again and simplifies
the process vastly as no additional communication channel is needed anymore.
---
 bin/gdbmacros/gdbmacros.cpp             |  50 +++---
 src/plugins/debugger/debuggerplugin.cpp |   2 +-
 src/plugins/debugger/gdbengine.cpp      | 193 +++++++++++++++++++++++-
 src/plugins/debugger/gdbengine.h        |   3 +
 src/plugins/debugger/gdbmi.cpp          |  30 ++--
 src/plugins/debugger/gdbmi.h            |  22 +--
 6 files changed, 243 insertions(+), 57 deletions(-)

diff --git a/bin/gdbmacros/gdbmacros.cpp b/bin/gdbmacros/gdbmacros.cpp
index 7a304607b6c..0a94e527b81 100644
--- a/bin/gdbmacros/gdbmacros.cpp
+++ b/bin/gdbmacros/gdbmacros.cpp
@@ -216,7 +216,8 @@ QT_END_NAMESPACE
 // this can be mangled typenames of nested templates, each char-by-char
 // comma-separated integer list
 static char qDumpInBuffer[10000];
-static char qDumpBuffer[1000];
+static char qDumpOutBuffer[100000];
+static char qDumpSize[20];
 
 namespace {
 
@@ -443,27 +444,28 @@ QDumper::~QDumper()
 {
     flush();
 
-    char buf[30];
-    int len = qsnprintf(buf, sizeof(buf) - 1, "%d^done\n", token);
-    write(buf, len);
+    //char buf[30];
+    //int len = qsnprintf(buf, sizeof(buf) - 1, "%d^done\n", token);
+    //write(buf, len);
 }
 
 void QDumper::write(const void *buf, int len)
 {
-    ::fwrite(buf, len, 1, stdout);
-    ::fflush(stdout);
+    //::fwrite(buf, len, 1, stdout);
+    //::fflush(stdout);
 }
 
 void QDumper::flush()
 {
-    if (pos != 0) {
-        char buf[30];
-        int len = qsnprintf(buf, sizeof(buf) - 1, "%d#%d,", token, pos);
-        write(buf, len);
-        write(qDumpBuffer, pos);
-        write("\n", 1);
-        pos = 0;
-    }
+    put(0);
+    //if (pos != 0) {
+    //    char buf[30];
+    //    int len = qsnprintf(buf, sizeof(buf) - 1, "%d#%d,", token, pos);
+    //    write(buf, len);
+    //    write(qDumpOutBuffer, pos);
+    //    write("\n", 1);
+    //    pos = 0;
+   // }
 }
 
 void QDumper::setupTemplateParameters()
@@ -489,49 +491,49 @@ void QDumper::setupTemplateParameters()
 QDumper &QDumper::operator<<(unsigned long long c)
 {
     checkFill();
-    pos += sprintf(qDumpBuffer + pos, "%llu", c);
+    pos += sprintf(qDumpOutBuffer + pos, "%llu", c);
     return *this;
 }
 
 QDumper &QDumper::operator<<(unsigned long c)
 {
     checkFill();
-    pos += sprintf(qDumpBuffer + pos, "%lu", c);
+    pos += sprintf(qDumpOutBuffer + pos, "%lu", c);
     return *this;
 }
 
 QDumper &QDumper::operator<<(float d)
 {
     checkFill();
-    pos += sprintf(qDumpBuffer + pos, "%f", d);
+    pos += sprintf(qDumpOutBuffer + pos, "%f", d);
     return *this;
 }
 
 QDumper &QDumper::operator<<(double d)
 {
     checkFill();
-    pos += sprintf(qDumpBuffer + pos, "%f", d);
+    pos += sprintf(qDumpOutBuffer + pos, "%f", d);
     return *this;
 }
 
 QDumper &QDumper::operator<<(unsigned int i)
 {
     checkFill();
-    pos += sprintf(qDumpBuffer + pos, "%u", i);
+    pos += sprintf(qDumpOutBuffer + pos, "%u", i);
     return *this;
 }
 
 QDumper &QDumper::operator<<(long c)
 {
     checkFill();
-    pos += sprintf(qDumpBuffer + pos, "%ld", c);
+    pos += sprintf(qDumpOutBuffer + pos, "%ld", c);
     return *this;
 }
 
 QDumper &QDumper::operator<<(int i)
 {
     checkFill();
-    pos += sprintf(qDumpBuffer + pos, "%d", i);
+    pos += sprintf(qDumpOutBuffer + pos, "%d", i);
     return *this;
 }
 
@@ -555,21 +557,21 @@ QDumper &QDumper::operator<<(const void *p)
 
 void QDumper::checkFill()
 {
-    if (pos >= int(sizeof(qDumpBuffer)) - 100)
+    if (pos >= int(sizeof(qDumpOutBuffer)) - 100)
         flush();
 }
 
 void QDumper::put(char c)
 {
     checkFill();
-    qDumpBuffer[pos++] = c;
+    qDumpOutBuffer[pos++] = c;
 }
 
 void QDumper::addCommaIfNeeded()
 {
     if (pos == 0)
         return;
-    char c = qDumpBuffer[pos - 1];
+    char c = qDumpOutBuffer[pos - 1];
     if (c == '}' || c == '"' || c == ']')
         put(',');
 }
diff --git a/src/plugins/debugger/debuggerplugin.cpp b/src/plugins/debugger/debuggerplugin.cpp
index f62140129ec..a42c1038204 100644
--- a/src/plugins/debugger/debuggerplugin.cpp
+++ b/src/plugins/debugger/debuggerplugin.cpp
@@ -928,7 +928,7 @@ void DebuggerPlugin::readSettings()
 
     m->m_skipKnownFrames  = s->value("SkipKnownFrames", false).toBool();
     m->m_debugDumpers     = s->value("DebugDumpers", false).toBool();
-    m->m_useCustomDumpers = s->value("UseCustomDupers", false).toBool();
+    m->m_useCustomDumpers = s->value("UseCustomDumpers", true).toBool();
     m->m_useFastStart     = s->value("UseFastStart", false).toBool();
     m->m_useToolTips      = s->value("UseToolTips", false).toBool();
     m->m_useTerminal      = s->value("UseTerminal", false).toBool();
diff --git a/src/plugins/debugger/gdbengine.cpp b/src/plugins/debugger/gdbengine.cpp
index a6d426d21da..ba1042aff8a 100644
--- a/src/plugins/debugger/gdbengine.cpp
+++ b/src/plugins/debugger/gdbengine.cpp
@@ -113,6 +113,7 @@ enum GdbCommandType
     GdbInfoProc,
     GdbQueryDataDumper1,
     GdbQueryDataDumper2,
+    GdbQueryDataDumper3,
 
     BreakCondition = 200,
     BreakEnablePending,
@@ -144,7 +145,8 @@ enum GdbCommandType
     WatchToolTip,
     WatchDumpCustomSetup,
     WatchDumpCustomValue1,           // waiting for gdb ack
-    WatchDumpCustomValue2,           // waiting for actual data
+    WatchDumpCustomValue2,           // waiting for actual data (fd version)
+    WatchDumpCustomValue3,           // waiting for actual data (buffer version)
     WatchDumpCustomEditValue,
 };
 
@@ -807,6 +809,9 @@ void GdbEngine::handleResult(const GdbResultRecord & record, int type,
         case GdbQueryDataDumper2:
             handleQueryDataDumper2(record);
             break;
+        case GdbQueryDataDumper3:
+            handleQueryDataDumper3(record);
+            break;
 
         case BreakList:
             handleBreakList(record);
@@ -883,6 +888,9 @@ void GdbEngine::handleResult(const GdbResultRecord & record, int type,
         case WatchDumpCustomValue2:
             handleDumpCustomValue2(record, cookie.value<WatchData>());
             break;
+        case WatchDumpCustomValue3:
+            handleDumpCustomValue3(record, cookie.value<WatchData>());
+            break;
         case WatchDumpCustomSetup:
             handleDumpCustomSetup(record);
             break;
@@ -1562,6 +1570,7 @@ bool GdbEngine::startDebugger()
     //sendCommand("set confirm off");
     //sendCommand("set pagination off");
     sendCommand("set breakpoint pending on", BreakEnablePending);
+    sendCommand("set print elements 10000");
 
     // one of the following is needed to prevent crashes in gdb on code like:
     //  template <class T> T foo() { return T(0); }
@@ -3081,11 +3090,12 @@ void GdbEngine::runCustomDumper(const WatchData & data0, bool dumpChildren)
     // create response slot for socket data
     QVariant var;
     var.setValue(data);
-    sendSynchronizedCommand(QString(), WatchDumpCustomValue2, var);
+    //sendSynchronizedCommand(QString(), WatchDumpCustomValue2, var);
 
     // this increases the probability that gdb spits out output it
     // has collected so far
     //sendCommand("p qDumpInBuffer");
+    sendSynchronizedCommand("p (char*)qDumpOutBuffer", WatchDumpCustomValue3, var);
 }
 
 void GdbEngine::createGdbVariable(const WatchData &data)
@@ -3360,6 +3370,73 @@ void GdbEngine::handleQueryDataDumper2(const GdbResultRecord &record)
     //qDebug() << "DATA DUMPERS AVAILABLE" << m_availableSimpleDumpers;
 }
 
+void GdbEngine::handleQueryDataDumper3(const GdbResultRecord &record)
+{
+#if 1
+    // is this the official gdb response. However, it won't contain
+    // interesting data other than the information that 'real' data
+    // either already arrived or is still in the pipe. So we do
+    // _not_ register this result for counting purposes, this will
+    // be done by the 'real' result (with resultClass == GdbResultCustomDone)
+    //qDebug() << "DATA DUMPER TRIAL:" << record.toString();
+    //GdbMi output = record.data.findChild("customvaluecontents");
+    GdbMi output = record.data.findChild("consolestreamoutput");
+    QByteArray out = output.data();
+    out = out.mid(out.indexOf('"') + 1);
+    out = out.replace('\\', "");
+    out = out.left(out.lastIndexOf('"'));
+    out = "result={" + out + "}";
+    qDebug() << "OUTPUT: " << out;
+
+    GdbMi contents;
+    contents.fromString(out);
+    GdbMi simple = contents.findChild("dumpers");
+    m_namespace = contents.findChild("namespace").data();
+    GdbMi qtversion = contents.findChild("qtversion");
+    if (qtversion.children().size() == 3) {
+        m_qtVersion = (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;
+    } else {
+        m_qtVersion = 0;
+    }
+   
+    qDebug() << "OUTPUT: " << out;
+    qDebug() << "CONTENTS: " << contents.toString();
+    qDebug() << "SIMPLE DUMPERS: " << simple.toString();
+    m_availableSimpleDumpers.clear();
+    foreach (const GdbMi &item, simple.children())
+        m_availableSimpleDumpers.append(item.data());
+    if (m_availableSimpleDumpers.isEmpty()) {
+        m_dataDumperState = DataDumperUnavailable;
+        QMessageBox::warning(q->mainWindow(),
+            tr("Cannot find special data dumpers"),
+            tr("The debugged binary does not contain information needed for "
+                    "nice display of Qt data types.\n\n"
+                    "Try might want to try include the file\n\n"
+                    ".../ide/main/bin/gdbmacros/gdbmacros.cpp'\n\n"
+                    "into your project directly.")
+                );
+    } else {
+        m_dataDumperState = DataDumperAvailable;
+    }
+    qDebug() << "DATA DUMPERS AVAILABLE" << m_availableSimpleDumpers;
+#else
+    // divert this to the fd version
+    GdbMi output = record.data.findChild("consolestreamoutput");
+    QByteArray out = output.data();
+    out = out.mid(out.indexOf('=') + 3);
+    out = out.replace("\\\\", "\\");
+    out = out.left(out.lastIndexOf('"'));
+    out = "dummy={customvaluecontents=\"{" + out + "}\"}";
+    GdbResultRecord record1 = record;
+    record1.data = GdbMi();
+    record1.data.fromString(out);
+    handleQueryDataDumper2(record1);
+#endif
+}
+
 void GdbEngine::sendWatchParameters(const QByteArray &params0)
 {
     QByteArray params = params0;
@@ -3596,6 +3673,115 @@ void GdbEngine::handleDumpCustomValue2(const GdbResultRecord &record,
     }
 }
 
+void GdbEngine::handleDumpCustomValue3(const GdbResultRecord &record,
+    const WatchData &data0)
+{
+    WatchData data = data0;
+    QTC_ASSERT(data.isValid(), return);
+    qDebug() << "CUSTOM VALUE RESULT: " << record.toString();
+    qDebug() << "FOR DATA: " << data.toString() << record.resultClass;
+    if (record.resultClass == GdbResultDone) {
+        //GdbMi output = record.data.findChild("customvaluecontents");
+
+        GdbMi output = record.data.findChild("consolestreamoutput");
+        QByteArray out = output.data();
+        out = out.mid(out.indexOf('"') + 1);
+        out = out.replace('\\', "");
+        out = out.left(out.lastIndexOf('"'));
+        out = "result={" + out + "}";
+        qDebug() << "OUTPUT: " << out;
+
+        GdbMi contents;
+        contents.fromString(out);
+
+        //qDebug() << "HANDLE VALUE CONTENTS: " << output.toString(true);
+        if (!contents.isValid()) {
+             qDebug() << "INVALID";
+             // custom dumper produced no output
+             if (data.isValueNeeded())
+                 data.setValue("<unknown>");
+             if (data.isTypeNeeded())
+                 data.setType("<unknown>");
+             if (data.isChildrenNeeded())
+                 data.setChildCount(0);
+             if (data.isChildCountNeeded())
+                 data.setChildCount(0);
+             data.setValueToolTip("<custom dumper produced no output>");
+             insertData(data);
+        } else {
+            //GdbMi contents;
+            //qDebug() << "OUTPUT" << output.toString(true);
+            //contents.fromString(output.data());
+            qDebug() << "CONTENTS" << contents.toString(true);
+            setWatchDataType(data, contents.findChild("type"));
+            setWatchDataValue(data, contents.findChild("value"),
+                contents.findChild("valueencoded").data().toInt());
+            setWatchDataAddress(data, contents.findChild("addr"));
+            setWatchDataChildCount(data, contents.findChild("numchild"));
+            setWatchDataValueToolTip(data, contents.findChild("valuetooltip"));
+            setWatchDataValueDisabled(data, contents.findChild("valuedisabled"));
+            setWatchDataEditValue(data, contents.findChild("editvalue"));
+            if (qq->watchHandler()->isDisplayedIName(data.iname)) {
+                GdbMi editvalue = contents.findChild("editvalue");
+                if (editvalue.isValid()) {
+                    setWatchDataEditValue(data, editvalue);
+                    qq->watchHandler()->showEditValue(data);
+                }
+            }
+            if (!qq->watchHandler()->isExpandedIName(data.iname))
+                data.setChildrenUnneeded();
+            GdbMi children = contents.findChild("children");
+            if (children.isValid() || !qq->watchHandler()->isExpandedIName(data.iname))
+                data.setChildrenUnneeded();
+            data.setValueUnneeded();
+
+            // try not to repeat data too often
+            WatchData childtemplate;
+            setWatchDataType(childtemplate, contents.findChild("childtype"));
+            setWatchDataChildCount(childtemplate, contents.findChild("childnumchild"));
+            //qDebug() << "DATA: " << data.toString();
+            insertData(data);
+            foreach (GdbMi item, children.children()) {
+                WatchData data1 = childtemplate;
+                data1.name = item.findChild("name").data();
+                data1.iname = data.iname + "." + data1.name;
+                //qDebug() << "NAMEENCODED: " << item.findChild("nameencoded").data()
+                //    << item.findChild("nameencoded").data()[1];
+                if (item.findChild("nameencoded").data()[0] == '1')
+                    data1.name = QByteArray::fromBase64(data1.name.toUtf8());
+                QString key = item.findChild("key").data();
+                if (!key.isEmpty())
+                    data1.name += " (" + key + ")";
+                setWatchDataType(data1, item.findChild("type"));
+                setWatchDataExpression(data1, item.findChild("exp"));
+                setWatchDataChildCount(data1, item.findChild("numchild"));
+                setWatchDataValue(data1, item.findChild("value"),
+                    item.findChild("valueencoded").data().toInt());
+                setWatchDataAddress(data1, item.findChild("addr"));
+                setWatchDataValueToolTip(data1, item.findChild("valuetooltip"));
+                setWatchDataValueDisabled(data1, item.findChild("valuedisabled"));
+                if (!qq->watchHandler()->isExpandedIName(data1.iname))
+                    data1.setChildrenUnneeded();
+                //qDebug() << "HANDLE CUSTOM SUBCONTENTS:" << data1.toString();
+                insertData(data1);
+            }
+        }
+        //qDebug() << "HANDLE CUSTOM VALUE CONTENTS: " << data.toString();
+    } else if (record.resultClass == GdbResultError) {
+        // FIXME: Should not happen here, i.e. could be removed
+        QString msg = record.data.findChild("msg").data();
+        //qDebug() << "CUSTOM DUMPER ERROR MESSAGE: " << msg;
+        if (msg.startsWith("The program being debugged was sig"))
+            msg = strNotInScope;
+        if (msg.startsWith("The program being debugged stopped while"))
+            msg = strNotInScope;
+        data.setError(msg);
+        insertData(data);
+    } else {
+        qDebug() << "STRANGE CUSTOM DUMPER RESULT DATA: " << data.toString();
+    }
+}
+
 void GdbEngine::updateLocals()
 {
     setTokenBarrier();
@@ -4021,7 +4207,8 @@ void GdbEngine::tryLoadCustomDumpers()
     sendCommand("call qDumpObjectData440(1,%1+1,0,0,0,0,0,0)",
         GdbQueryDataDumper1);
     // create response slot for socket data
-    sendCommand(QString(), GdbQueryDataDumper2);
+    //sendCommand(QString(), GdbQueryDataDumper2);
+    sendCommand("p (char*)qDumpOutBuffer", GdbQueryDataDumper3);
 }
 
 
diff --git a/src/plugins/debugger/gdbengine.h b/src/plugins/debugger/gdbengine.h
index 60493a53e58..1113955ab86 100644
--- a/src/plugins/debugger/gdbengine.h
+++ b/src/plugins/debugger/gdbengine.h
@@ -307,8 +307,11 @@ private:
         const WatchData &cookie);
     void handleQueryDataDumper1(const GdbResultRecord &record);
     void handleQueryDataDumper2(const GdbResultRecord &record);
+    void handleQueryDataDumper3(const GdbResultRecord &record);
     void handleDumpCustomValue2(const GdbResultRecord &record,
         const WatchData &cookie);
+    void handleDumpCustomValue3(const GdbResultRecord &record,
+        const WatchData &cookie);
     void handleDumpCustomEditValue(const GdbResultRecord &record);
     void handleDumpCustomSetup(const GdbResultRecord &record);
     void handleStackListLocals(const GdbResultRecord &record);
diff --git a/src/plugins/debugger/gdbmi.cpp b/src/plugins/debugger/gdbmi.cpp
index 88060d7b350..d3fbeb44281 100644
--- a/src/plugins/debugger/gdbmi.cpp
+++ b/src/plugins/debugger/gdbmi.cpp
@@ -46,20 +46,20 @@ QTextStream & operator<<(QTextStream & os, const GdbMi & mi)
     return os << mi.toString();
 }
 
-//static void skipSpaces(const GdbMi::Char *&from, const GdbMi::Char *to)
+//static void skipSpaces(const char *&from, const char *to)
 //{
 //    while (from != to && QChar(*from).isSpace())
 //        ++from;
 //}
 
 
-void GdbMi::parseResultOrValue(const Char *&from, const Char *to)
+void GdbMi::parseResultOrValue(const char *&from, const char *to)
 {
     //skipSpaces(from, to);
     while (from != to && QChar(*from).isSpace())
         ++from;
 
-    //qDebug() << "parseResultOrValue: " << QByteArray::fromLatin1(from, to - from);
+    //qDebug() << "parseResultOrValue: " << QByteArray(from, to - from);
     parseValue(from, to);
     if (isValid()) {
         //qDebug() << "no valid result in " << QByteArray::fromLatin1(from, to - from);
@@ -67,7 +67,7 @@ void GdbMi::parseResultOrValue(const Char *&from, const Char *to)
     }
     if (from == to || *from == '(')
         return;
-    const Char *ptr = from;
+    const char *ptr = from;
     while (ptr < to && *ptr != '=') {
         //qDebug() << "adding" << QChar(*ptr) << "to name";
         ++ptr;
@@ -80,7 +80,7 @@ void GdbMi::parseResultOrValue(const Char *&from, const Char *to)
     }
 }
 
-QByteArray GdbMi::parseCString(const Char *&from, const Char *to)
+QByteArray GdbMi::parseCString(const char *&from, const char *to)
 {
     QByteArray result;
     //qDebug() << "parseCString: " << QByteArray::fromUtf16(from, to - from);
@@ -88,7 +88,7 @@ QByteArray GdbMi::parseCString(const Char *&from, const Char *to)
         qDebug() << "MI Parse Error, double quote expected";
         return QByteArray();
     }
-    const Char *ptr = from;
+    const char *ptr = from;
     ++ptr;
     while (ptr < to) {
         if (*ptr == '"') {
@@ -115,7 +115,7 @@ QByteArray GdbMi::parseCString(const Char *&from, const Char *to)
     return result;
 }
 
-void GdbMi::parseValue(const Char *&from, const Char *to)
+void GdbMi::parseValue(const char *&from, const char *to)
 {
     //qDebug() << "parseValue: " << QByteArray::fromUtf16(from, to - from);
     switch (*from) {
@@ -135,7 +135,7 @@ void GdbMi::parseValue(const Char *&from, const Char *to)
 }
 
 
-void GdbMi::parseTuple(const Char *&from, const Char *to)
+void GdbMi::parseTuple(const char *&from, const char *to)
 {
     //qDebug() << "parseTuple: " << QByteArray::fromUtf16(from, to - from);
     QTC_ASSERT(*from == '{', /**/);
@@ -143,7 +143,7 @@ void GdbMi::parseTuple(const Char *&from, const Char *to)
     parseTuple_helper(from, to);
 }
 
-void GdbMi::parseTuple_helper(const Char *&from, const Char *to)
+void GdbMi::parseTuple_helper(const char *&from, const char *to)
 {
     //qDebug() << "parseTuple_helper: " << QByteArray::fromUtf16(from, to - from);
     m_type = Tuple;
@@ -163,7 +163,7 @@ void GdbMi::parseTuple_helper(const Char *&from, const Char *to)
     }
 }
 
-void GdbMi::parseList(const Char *&from, const Char *to)
+void GdbMi::parseList(const char *&from, const char *to)
 {
     //qDebug() << "parseList: " << QByteArray::fromUtf16(from, to - from);
     QTC_ASSERT(*from == '[', /**/);
@@ -267,8 +267,8 @@ QByteArray GdbMi::toString(bool multiline, int indent) const
 
 void GdbMi::fromString(const QByteArray &ba)
 {
-    const Char *from = ba.constBegin();
-    const Char *to = ba.constEnd();
+    const char *from = ba.constBegin();
+    const char *to = ba.constEnd();
     parseResultOrValue(from, to);
 }
 
@@ -449,16 +449,16 @@ static struct Tester {
         }
         for (int i = from; i < to; ++i) {
             if (str[i] == '{')
-                result += "{\n" + QByteArray(2*++indent + 1, QChar(' '));
+                result += "{\n" + QByteArray(2*++indent + 1, ' ');
             else if (str[i] == '}') {
                 if (!result.isEmpty() && result[result.size() - 1] != '\n')
                     result += "\n";
-                result += QByteArray(2*--indent + 1, QChar(' ')) + "}\n";
+                result += QByteArray(2*--indent + 1, ' ') + "}\n";
             }
             else if (str[i] == ',') {
                 if (true || !result.isEmpty() && result[result.size() - 1] != '\n')
                     result += "\n";
-                result += QByteArray(2*indent, QChar(' '));
+                result += QByteArray(2*indent, ' ');
             }
             else
                 result += str[i];
diff --git a/src/plugins/debugger/gdbmi.h b/src/plugins/debugger/gdbmi.h
index 0e6c36e9756..21810eed40e 100644
--- a/src/plugins/debugger/gdbmi.h
+++ b/src/plugins/debugger/gdbmi.h
@@ -34,8 +34,6 @@
 #ifndef DEBUGGER_GDBMI_H
 #define DEBUGGER_GDBMI_H
 
-#include <qglobal.h>
-
 #include <QtCore/QByteArray>
 #include <QtCore/QList>
 
@@ -125,8 +123,8 @@ public:
     inline const QList<GdbMi> &children() const { return m_children; }
     inline int childCount() const { return m_children.size(); }
 
-    const GdbMi & childAt(int index) const { return m_children[index]; } 
-    GdbMi & childAt(int index) { return m_children[index]; }
+    const GdbMi &childAt(int index) const { return m_children[index]; } 
+    GdbMi &childAt(int index) { return m_children[index]; }
     GdbMi findChild(const QByteArray &name) const;
     GdbMi findChild(const QByteArray &name, const QByteArray &defaultString) const;
 
@@ -138,14 +136,12 @@ private:
     friend class GdbResultRecord;
     friend class GdbEngine;
 
-    //typedef ushort Char;
-    typedef char Char;
-    static QByteArray parseCString(const Char *&from, const Char *to);
-    void parseResultOrValue(const Char *&from, const Char *to);
-    void parseValue(const Char *&from, const Char *to);
-    void parseTuple(const Char *&from, const Char *to);
-    void parseTuple_helper(const Char *&from, const Char *to);
-    void parseList(const Char *&from, const Char *to);
+    static QByteArray parseCString(const char *&from, const char *to);
+    void parseResultOrValue(const char *&from, const char *to);
+    void parseValue(const char *&from, const char *to);
+    void parseTuple(const char *&from, const char *to);
+    void parseTuple_helper(const char *&from, const char *to);
+    void parseList(const char *&from, const char *to);
 
     void dumpChildren(QByteArray *str, bool multiline, int indent) const;
 };
@@ -171,8 +167,6 @@ public:
     int            token;
     GdbResultClass resultClass;
     GdbMi          data;
-private:
-    friend class GdbMi;
 };
 
 } // namespace Internal
-- 
GitLab