qmlcppengine.cpp 17.8 KB
Newer Older
Tobias Hunger's avatar
Tobias Hunger committed
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
/**************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** No Commercial Usage
**
** This file contains pre-release code and may not be distributed.
** You may use this file in accordance with the terms and conditions
** contained in the Technology Preview License Agreement accompanying
** this package.
**
** GNU Lesser General Public License Usage
**
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file.  Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights.  These rights are described in the Nokia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** If you have questions regarding the use of this file, please contact
** Nokia at qt-info@nokia.com.
**
**************************************************************************/
33

34
#include "qmlcppengine.h"
35

36
37
#include "debuggercore.h"
#include "debuggerstartparameters.h"
hjk's avatar
hjk committed
38
#include "stackhandler.h"
39

40
41
#include <utils/qtcassert.h>

42
43

namespace Debugger {
44
namespace Internal {
45

46
47
48
49
enum { debug = 0 };

#define EDEBUG(s) do { if (debug) qDebug() << s; } while (0)

50
51
const int ConnectionWaitTimeMs = 5000;

52
53
54
55
56
57
DebuggerEngine *createCdbEngine(const DebuggerStartParameters &,
    DebuggerEngine *masterEngine, QString *);
DebuggerEngine *createGdbEngine(const DebuggerStartParameters &,
    DebuggerEngine *masterEngine);
DebuggerEngine *createQmlEngine(const DebuggerStartParameters &,
    DebuggerEngine *masterEngine);
58
59
60

DebuggerEngine *createQmlCppEngine(const DebuggerStartParameters &sp)
{
61
    QmlCppEngine *newEngine = new QmlCppEngine(sp);
hjk's avatar
hjk committed
62
    if (newEngine->cppEngine())
63
        return newEngine;
hjk's avatar
hjk committed
64
65
    delete newEngine;
    return 0;
66
}
hjk's avatar
hjk committed
67

hjk's avatar
hjk committed
68
69
70
71
72
73
74
75

////////////////////////////////////////////////////////////////////////
//
// QmlCppEnginePrivate
//
////////////////////////////////////////////////////////////////////////

class QmlCppEnginePrivate : public QObject
76
{
hjk's avatar
hjk committed
77
78
    Q_OBJECT

79
public:
hjk's avatar
hjk committed
80
81
    QmlCppEnginePrivate(QmlCppEngine *parent,
            const DebuggerStartParameters &sp);
82
    ~QmlCppEnginePrivate() {}
83

hjk's avatar
hjk committed
84
85
86
87
private slots:
    void cppStackChanged();
    void qmlStackChanged();

88
private:
hjk's avatar
hjk committed
89
90
    friend class QmlCppEngine;
    QmlCppEngine *q;
91
    DebuggerEngine *m_qmlEngine;
92
93
    DebuggerEngine *m_cppEngine;
    DebuggerEngine *m_activeEngine;
94
    int m_stackBoundary;
95
96
};

hjk's avatar
hjk committed
97
98
99

QmlCppEnginePrivate::QmlCppEnginePrivate(QmlCppEngine *parent,
        const DebuggerStartParameters &sp)
100
  : q(parent)
101
{
102
103
104
    m_stackBoundary = 0;
    m_cppEngine = 0;
    m_activeEngine = 0;
hjk's avatar
hjk committed
105
    m_qmlEngine = createQmlEngine(sp, q);
106

hjk's avatar
hjk committed
107
108
    if (sp.cppEngineType == GdbEngineType) {
        m_cppEngine = createGdbEngine(sp, q);
109
    } else {
110
        QString errorMessage;
hjk's avatar
hjk committed
111
112
        m_cppEngine = createCdbEngine(sp, q, &errorMessage);
        if (!m_cppEngine) {
113
            qWarning("%s", qPrintable(errorMessage));
114
115
            return;
        }
116
117
    }

hjk's avatar
hjk committed
118
119
120
121
122
123
    m_activeEngine = m_cppEngine;

    connect(m_cppEngine->stackHandler()->model(), SIGNAL(modelReset()),
        SLOT(cppStackChanged()), Qt::QueuedConnection);
    connect(m_qmlEngine->stackHandler()->model(), SIGNAL(modelReset()),
        SLOT(qmlStackChanged()), Qt::QueuedConnection);
124
125
    connect(m_cppEngine, SIGNAL(stackFrameCompleted()), q, SIGNAL(stackFrameCompleted()));
    connect(m_qmlEngine, SIGNAL(stackFrameCompleted()), q, SIGNAL(stackFrameCompleted()));
hjk's avatar
hjk committed
126
}
127

hjk's avatar
hjk committed
128
129
130
131
132
133
134
135
136
137
void QmlCppEnginePrivate::cppStackChanged()
{
    const QLatin1String firstFunction("QScript::FunctionWrapper::proxyCall");
    StackFrames frames;
    foreach (const StackFrame &frame, m_cppEngine->stackHandler()->frames()) {
        if (frame.function.endsWith(firstFunction))
            break;
        frames.append(frame);
    }
    int level = frames.size();
138
    m_stackBoundary = level;
hjk's avatar
hjk committed
139
140
141
    foreach (StackFrame frame, m_qmlEngine->stackHandler()->frames()) {
        frame.level = level++;
        frames.append(frame);
142
    }
hjk's avatar
hjk committed
143
144
145
146
147
    q->stackHandler()->setFrames(frames);
}

void QmlCppEnginePrivate::qmlStackChanged()
{
148
149
150
    StackFrames frames = m_qmlEngine->stackHandler()->frames();
    q->stackHandler()->setFrames(frames);
    m_stackBoundary = frames.size();
hjk's avatar
hjk committed
151
152
153
154
155
156
157
158
159
160
161
162
}


////////////////////////////////////////////////////////////////////////
//
// QmlCppEngine
//
////////////////////////////////////////////////////////////////////////

QmlCppEngine::QmlCppEngine(const DebuggerStartParameters &sp)
    : DebuggerEngine(sp), d(new QmlCppEnginePrivate(this, sp))
{
163
164
165
//    setStateDebugging(true);
//    d->m_cppEngine->setStateDebugging(true);
//    d->m_qmlEngine->setStateDebugging(true);
166
167
168
169
}

QmlCppEngine::~QmlCppEngine()
{
170
171
    delete d->m_qmlEngine;
    delete d->m_cppEngine;
172
173
}

174
bool QmlCppEngine::setToolTipExpression(const QPoint & mousePos,
175
        TextEditor::ITextEditor *editor, const DebuggerToolTipContext &ctx)
176
{
177
    return d->m_activeEngine->setToolTipExpression(mousePos, editor, ctx);
178
179
}

hjk's avatar
hjk committed
180
181
void QmlCppEngine::updateWatchData(const WatchData &data,
    const WatchUpdateFlags &flags)
182
{
183
    d->m_activeEngine->updateWatchData(data, flags);
184
185
186
187
}

void QmlCppEngine::watchPoint(const QPoint &point)
{
188
    d->m_cppEngine->watchPoint(point);
189
190
}

191
void QmlCppEngine::fetchMemory(MemoryAgent *ma, QObject *obj,
192
193
        quint64 addr, quint64 length)
{
194
    d->m_cppEngine->fetchMemory(ma, obj, addr, length);
195
196
}

197
void QmlCppEngine::fetchDisassembler(DisassemblerAgent *da)
198
{
199
    d->m_cppEngine->fetchDisassembler(da);
200
201
202
203
}

void QmlCppEngine::activateFrame(int index)
{
204
205
206
207
    if (index >= d->m_stackBoundary)
        d->m_qmlEngine->activateFrame(index - d->m_stackBoundary);
    else
        d->m_cppEngine->activateFrame(index);
208
    stackHandler()->setCurrentIndex(index);
209
210
211
212
}

void QmlCppEngine::reloadModules()
{
213
    d->m_cppEngine->reloadModules();
214
215
216
217
}

void QmlCppEngine::examineModules()
{
218
    d->m_cppEngine->examineModules();
219
220
221
222
}

void QmlCppEngine::loadSymbols(const QString &moduleName)
{
223
    d->m_cppEngine->loadSymbols(moduleName);
224
225
226
227
}

void QmlCppEngine::loadAllSymbols()
{
228
    d->m_cppEngine->loadAllSymbols();
229
230
231
232
}

void QmlCppEngine::requestModuleSymbols(const QString &moduleName)
{
233
    d->m_cppEngine->requestModuleSymbols(moduleName);
234
235
236
237
}

void QmlCppEngine::reloadRegisters()
{
238
    d->m_cppEngine->reloadRegisters();
239
240
241
242
}

void QmlCppEngine::reloadSourceFiles()
{
243
    d->m_cppEngine->reloadSourceFiles();
244
245
246
247
}

void QmlCppEngine::reloadFullStack()
{
248
    d->m_cppEngine->reloadFullStack();
249
250
251
252
}

void QmlCppEngine::setRegisterValue(int regnr, const QString &value)
{
253
    d->m_cppEngine->setRegisterValue(regnr, value);
254
255
256
257
258
}

unsigned QmlCppEngine::debuggerCapabilities() const
{
    // ### this could also be an OR of both engines' capabilities
259
    return d->m_cppEngine->debuggerCapabilities();
260
261
}

hjk's avatar
hjk committed
262
bool QmlCppEngine::isSynchronous() const
263
{
264
    return d->m_activeEngine->isSynchronous();
265
266
}

267
QByteArray QmlCppEngine::qtNamespace() const
268
{
269
    return d->m_cppEngine->qtNamespace();
270
271
272
273
}

void QmlCppEngine::createSnapshot()
{
274
    d->m_cppEngine->createSnapshot();
275
276
277
278
}

void QmlCppEngine::updateAll()
{
279
    d->m_activeEngine->updateAll();
280
281
282
283
}

void QmlCppEngine::attemptBreakpointSynchronization()
{
284
    d->m_cppEngine->attemptBreakpointSynchronization();
285
    d->m_qmlEngine->attemptBreakpointSynchronization();
286
287
}

288
bool QmlCppEngine::acceptsBreakpoint(BreakpointId id) const
289
{
hjk's avatar
hjk committed
290
291
    return d->m_cppEngine->acceptsBreakpoint(id)
        || d->m_qmlEngine->acceptsBreakpoint(id);
292
293
}

294
295
void QmlCppEngine::selectThread(int index)
{
296
    d->m_cppEngine->selectThread(index);
297
298
}

hjk's avatar
hjk committed
299
300
void QmlCppEngine::assignValueInDebugger(const WatchData *data,
    const QString &expr, const QVariant &value)
301
{
hjk's avatar
hjk committed
302
    d->m_activeEngine->assignValueInDebugger(data, expr, value);
303
304
305
306
}

void QmlCppEngine::detachDebugger()
{
307
308
    d->m_qmlEngine->detachDebugger();
    d->m_cppEngine->detachDebugger();
309
310
311
}

void QmlCppEngine::executeStep()
312
313
314
{
    if (d->m_activeEngine == d->m_qmlEngine) {
        QTC_ASSERT(d->m_cppEngine->state() == InferiorRunOk, /**/);
315
316
        if (d->m_cppEngine->setupQmlStep(true))
            return; // Wait for callback to readyToExecuteQmlStep()
317
318
319
    } else {
        notifyInferiorRunRequested();
        d->m_cppEngine->executeStep();
320
321
322
    }
}

323
void QmlCppEngine::readyToExecuteQmlStep()
324
{
325
    notifyInferiorRunRequested();
326
    d->m_qmlEngine->executeStep();
327
328
329
330
}

void QmlCppEngine::executeStepOut()
{
331
    notifyInferiorRunRequested();
332
    d->m_activeEngine->executeStepOut();
333
334
335
336
}

void QmlCppEngine::executeNext()
{
337
    notifyInferiorRunRequested();
338
    d->m_activeEngine->executeNext();
339
340
341
342
}

void QmlCppEngine::executeStepI()
{
343
    notifyInferiorRunRequested();
344
    d->m_activeEngine->executeStepI();
345
346
347
348
}

void QmlCppEngine::executeNextI()
{
349
    notifyInferiorRunRequested();
350
    d->m_activeEngine->executeNextI();
351
352
353
354
}

void QmlCppEngine::executeReturn()
{
355
    notifyInferiorRunRequested();
356
    d->m_activeEngine->executeReturn();
357
358
359
360
}

void QmlCppEngine::continueInferior()
{
361
362
    EDEBUG("\nMASTER CONTINUE INFERIOR"
        << d->m_cppEngine->state() << d->m_qmlEngine->state());
363
364
365
366
367
    notifyInferiorRunRequested();
    if (d->m_cppEngine->state() == InferiorStopOk) {
        d->m_cppEngine->continueInferior();
    } else if (d->m_qmlEngine->state() == InferiorStopOk) {
        d->m_qmlEngine->continueInferior();
368
    } else {
369
370
371
        QTC_ASSERT(false, qDebug() << "MASTER CANNOT CONTINUE INFERIOR"
                << d->m_cppEngine->state() << d->m_qmlEngine->state());
        notifyEngineIll();
372
    }
373
374
375
376
}

void QmlCppEngine::interruptInferior()
{
377
    EDEBUG("\nMASTER INTERRUPT INFERIOR");
378
379
380
381
}

void QmlCppEngine::requestInterruptInferior()
{
382
    EDEBUG("\nMASTER REQUEST INTERUPT INFERIOR");
383
    DebuggerEngine::requestInterruptInferior();
384
    d->m_cppEngine->requestInterruptInferior();
385
386
}

387
void QmlCppEngine::executeRunToLine(const ContextData &data)
388
{
389
    d->m_activeEngine->executeRunToLine(data);
390
391
392
393
}

void QmlCppEngine::executeRunToFunction(const QString &functionName)
{
394
    d->m_activeEngine->executeRunToFunction(functionName);
395
396
}

397
void QmlCppEngine::executeJumpToLine(const ContextData &data)
398
{
399
    d->m_activeEngine->executeJumpToLine(data);
400
401
402
403
}

void QmlCppEngine::executeDebuggerCommand(const QString &command)
{
404
    d->m_cppEngine->executeDebuggerCommand(command);
405
406
}

407
408
/////////////////////////////////////////////////////////

409
void QmlCppEngine::setupEngine()
410
{
411
    EDEBUG("\nMASTER SETUP ENGINE");
412
413
    d->m_activeEngine = d->m_cppEngine;
    d->m_stackBoundary = 0;
414
415
    d->m_qmlEngine->setupSlaveEngine();
    d->m_cppEngine->setupSlaveEngine();
416
}
417

418
419
void QmlCppEngine::notifyEngineRunAndInferiorRunOk()
{
420
    EDEBUG("\nMASTER NOTIFY ENGINE RUN AND INFERIOR RUN OK");
421
    DebuggerEngine::notifyEngineRunAndInferiorRunOk();
422
423
}

424
425
void QmlCppEngine::notifyInferiorRunOk()
{
426
    EDEBUG("\nMASTER NOTIFY INFERIOR RUN OK");
427
428
429
    DebuggerEngine::notifyInferiorRunOk();
}

430
void QmlCppEngine::notifyInferiorSpontaneousStop()
431
{
432
    EDEBUG("\nMASTER SPONTANEOUS STOP OK");
433
    DebuggerEngine::notifyInferiorSpontaneousStop();
434
435
}

436
void QmlCppEngine::notifyInferiorShutdownOk()
437
{
438
    EDEBUG("\nMASTER INFERIOR SHUTDOWN OK");
439
    DebuggerEngine::notifyInferiorShutdownOk();
440
441
}

442
void QmlCppEngine::setupInferior()
443
{
444
    EDEBUG("\nMASTER SETUP INFERIOR");
445
446
    d->m_qmlEngine->setupSlaveInferior();
    d->m_cppEngine->setupSlaveInferior();
447
448
}

449
void QmlCppEngine::runEngine()
450
{
451
    EDEBUG("\nMASTER RUN ENGINE");
452
453
    d->m_qmlEngine->runSlaveEngine();
    d->m_cppEngine->runSlaveEngine();
454
455
}

456
void QmlCppEngine::shutdownInferior()
457
{
458
    EDEBUG("\nMASTER SHUTDOWN INFERIOR");
459
    d->m_qmlEngine->quitDebugger();
460
461
}

462
void QmlCppEngine::shutdownEngine()
463
{
464
    EDEBUG("\nMASTER SHUTDOWN ENGINE");
465
466
    d->m_qmlEngine->shutdownSlaveEngine();
    d->m_cppEngine->shutdownSlaveEngine();
467
468
}

469
void QmlCppEngine::setState(DebuggerState newState, bool forced)
470
{
471
472
473
    EDEBUG("SET MASTER STATE: " << newState);
    EDEBUG("  CPP STATE: " << d->m_cppEngine->state());
    EDEBUG("  QML STATE: " << d->m_qmlEngine->state());
474
    DebuggerEngine::setState(newState, forced);
475
476
}

477
478
void QmlCppEngine::slaveEngineStateChanged
    (DebuggerEngine *slaveEngine, const DebuggerState newState)
479
{
480
481
    DebuggerEngine *otherEngine = slaveEngine == d->m_cppEngine
         ? d->m_qmlEngine : d->m_cppEngine;
482

483
484
485
    EDEBUG("GOT SLAVE STATE: " << slaveEngine << newState);
    EDEBUG("  OTHER ENGINE: " << otherEngine << otherEngine->state());
    EDEBUG("  COMBINED ENGINE: " << this << state() << isDying());
486

487
    switch (newState) {
488
489
490
491
492
493
494
495
496
497
498
499
500
501

    case DebuggerNotReady:
    case InferiorUnrunnable:
        break;

    case EngineSetupRequested:
        break;

    case EngineSetupFailed:
        notifyEngineSetupFailed();
        break;

    case EngineSetupOk:
        if (otherEngine->state() == EngineSetupOk)
502
            notifyEngineSetupOk();
503
        else
504
            EDEBUG("... WAITING FOR OTHER ENGINE SETUP...");
505
506
507
508
509
510
511
        break;


    case InferiorSetupRequested:
        break;

    case InferiorSetupFailed:
512
513
514
515
        if (otherEngine->state() == InferiorRunOk)
            otherEngine->quitDebugger();
        else
            notifyInferiorSetupFailed();
516
517
518
519
520
521
        break;

    case InferiorSetupOk:
        if (otherEngine->state() == InferiorSetupOk)
            notifyInferiorSetupOk();
        else
522
            EDEBUG("... WAITING FOR OTHER INFERIOR SETUP...");
523
524
525
526
527
528
529
        break;


    case EngineRunRequested:
        break;

    case EngineRunFailed:
530
531
532
533
        if (otherEngine->state() == InferiorRunOk)
            otherEngine->quitDebugger();
        else
            notifyEngineRunFailed();
534
535
536
        break;


537
    case InferiorRunRequested:
538
539
540
541
542
543
544
        break;

    case InferiorRunFailed:
        notifyInferiorRunFailed();
        break;

    case InferiorRunOk:
hjk's avatar
hjk committed
545
        if (state() == EngineRunRequested) {
546
            if (otherEngine->state() == InferiorRunOk)
hjk's avatar
hjk committed
547
                notifyEngineRunAndInferiorRunOk();
548
            else if (otherEngine->state() == InferiorStopOk)
hjk's avatar
hjk committed
549
550
                notifyEngineRunAndInferiorStopOk();
            else
551
                EDEBUG("... WAITING FOR OTHER INFERIOR RUN");
hjk's avatar
hjk committed
552
553
        } else {
            if (otherEngine->state() == InferiorRunOk) {
554
                EDEBUG("PLANNED INFERIOR RUN");
hjk's avatar
hjk committed
555
                notifyInferiorRunOk();
556
557
            } else if (otherEngine->state() == InferiorStopOk) {
                EDEBUG("PLANNED SINGLE INFERIOR RUN");
hjk's avatar
hjk committed
558
            } else {
559
                EDEBUG(" **** INFERIOR RUN NOT OK ****");
hjk's avatar
hjk committed
560
561
            }
        }
562
563
564
        break;


565
    case InferiorStopRequested:
566
567
568
569
        break;

    case InferiorStopFailed:
        notifyInferiorStopFailed();
570
571
572
        break;

    case InferiorStopOk:
573
        if (isDying()) {
574
            EDEBUG("... AN INFERIOR STOPPED DURING SHUTDOWN ");
575
        } else {
576
577
578
579
580
581
            if (slaveEngine != d->m_activeEngine) {
                QString engineName = slaveEngine == d->m_cppEngine
                    ? QLatin1String("C++") : QLatin1String("QML");
                showStatusMessage(tr("%1 debugger activated").arg(engineName));
                d->m_activeEngine = slaveEngine;
            }
582
583
584
            if (otherEngine->state() == InferiorStopOk) {
                EDEBUG("... BOTH STOPPED ");
            } else if (otherEngine->state() == InferiorShutdownOk) {
585
                EDEBUG("... STOPP ");
586
            } else if (state() == InferiorStopRequested) {
587
                EDEBUG("... AN INFERIOR STOPPED EXPECTEDLY");
588
                notifyInferiorStopOk();
589
590
            } else if (state() == EngineRunRequested) {
                EDEBUG("... AN INFERIOR FAILED STARTUP, OTHER STOPPED EXPECTEDLY");
591
            } else {
592
                EDEBUG("... AN INFERIOR STOPPED SPONTANEOUSLY");
593
                notifyInferiorSpontaneousStop();
594
595
596
597
            }
        }
        break;

598
599

    case InferiorExitOk:
600
601
        break;

602
    case InferiorShutdownRequested:
603
604
        break;

605
606
607
608
609
    case InferiorShutdownFailed:
        notifyInferiorShutdownFailed();
        break;

    case InferiorShutdownOk:
610
611
612
613
614
615
        if (otherEngine->state() == InferiorShutdownOk) {
            if (state() == InferiorRunOk)
                notifyInferiorExited();
            else
                notifyInferiorShutdownOk();
        } else if (otherEngine->state() == InferiorRunOk) {
616
            otherEngine->quitDebugger();
617
        } else if (otherEngine->state() == InferiorStopOk) {
618
            otherEngine->quitDebugger();
619
620
621
622
623
624
        } else if (otherEngine->state() == EngineRunFailed) {
            EDEBUG("... INFERIOR STOPPED, OTHER ENGINE FAILED");
            notifyEngineRunFailed();
        } else if (otherEngine->state() == InferiorSetupFailed) {
            EDEBUG("... INFERIOR STOPPED, OTHER INFERIOR FAILED");
            notifyInferiorSetupFailed();
625
        }
626
627
628
        break;


629
630
631
    case EngineShutdownRequested:
        break;

632
633
    case EngineShutdownFailed:
        notifyEngineShutdownFailed();
634
635
        break;

636
637
    case EngineShutdownOk:
        if (otherEngine->state() == EngineShutdownOk)
638
            ; // Wait for DebuggerFinished.
639
        else
640
            EDEBUG("... WAITING FOR OTHER ENGINE SHUTDOWN...");
641
        break;
642
643
644


    case DebuggerFinished:
645
646
647
        if (otherEngine->state() == DebuggerFinished)
            notifyEngineShutdownOk();
        else
648
            EDEBUG("... WAITING FOR OTHER DEBUGGER TO FINISH...");
649
        break;
650
651
652
    }
}

653
654
void QmlCppEngine::handleRemoteSetupDone(int gdbServerPort, int qmlPort)
{
655
    EDEBUG("MASTER REMOTE SETUP DONE");
656
657
658
659
660
661
    d->m_qmlEngine->handleRemoteSetupDone(gdbServerPort, qmlPort);
    d->m_cppEngine->handleRemoteSetupDone(gdbServerPort, qmlPort);
}

void QmlCppEngine::handleRemoteSetupFailed(const QString &message)
{
662
    EDEBUG("MASTER REMOTE SETUP FAILED");
663
664
665
666
    d->m_qmlEngine->handleRemoteSetupFailed(message);
    d->m_cppEngine->handleRemoteSetupFailed(message);
}

667
668
669
670
671
DebuggerEngine *QmlCppEngine::cppEngine() const
{
    return d->m_cppEngine;
}

672
} // namespace Internal
673
} // namespace Debugger
hjk's avatar
hjk committed
674
675

#include "qmlcppengine.moc"