Commit c33ca52b authored by con's avatar con

Merge commit 'origin/1.1'

parents 237cd06b 1f4fcf8e
......@@ -13,11 +13,9 @@ General
* Completely reworked editor split mechanism.
Editing
* Completion for constructors in variable initialization.
* Some support for Obj-C++ //TODO: what does that mean more concrete?
* Some support for doxygen style comments //TODO: what does that mean more concrete?
* More intelligent adding of braces.
* Improved function argument completion.
* Improved function argument hint.
* More checkpoints in editor history.
* Ctrl-click for jumping to a symbol definition.
* Context help for form editor widgets.
......@@ -40,12 +38,12 @@ Debugging
* Make strategy to load shared objects configurable (auto-solib-add).
* Maximum stack depth configurable.
* Improved interaction in the Locals&Watchers view.
* Experimental cdb debugger.
Wizards
* It is now possible to choose file suffixes in the options dialog.
* Code of language change event is now generated correctly (added call
to base class).
* Generated header guards now adapt to file extension.
Designer
* Added signal/slot editor.
......
......@@ -223,14 +223,13 @@ QList<Symbol *> LookupContext::resolve(Name *name, const QList<Scope *> &visible
continue;
if (q->nameCount() > 1) {
Name *classOrNamespaceName = 0;
if (q->nameCount() == 1)
classOrNamespaceName = q->nameAt(0);
else
classOrNamespaceName = control()->qualifiedNameId(q->names(),
q->nameCount() - 1);
Name *classOrNamespaceName = control()->qualifiedNameId(q->names(),
q->nameCount() - 1);
if (Identifier *classOrNamespaceNameId = identifier(classOrNamespaceName)) {
if (classOrNamespaceNameId->isEqualTo(id))
continue;
}
const QList<Symbol *> resolvedClassOrNamespace =
resolveClassOrNamespace(classOrNamespaceName, visibleScopes);
......@@ -455,7 +454,7 @@ void LookupContext::expandFunction(Scope *scope,
expandedScopes->append(function->arguments());
if (QualifiedNameId *q = function->name()->asQualifiedNameId()) {
Name *nestedNameSpec = 0;
if (q->nameCount() == 1 && q->isGlobal())
if (q->nameCount() == 1)
nestedNameSpec = q->nameAt(0);
else
nestedNameSpec = control()->qualifiedNameId(q->names(), q->nameCount() - 1,
......
......@@ -1336,13 +1336,16 @@ void EditorManager::updateActions()
m_d->m_revertToSavedAction->setEnabled(curEditor != 0
&& !curEditor->file()->fileName().isEmpty() && curEditor->file()->isModified());
m_d->m_saveAsAction->setText(tr("Save %1 As...").arg(fName));
m_d->m_saveAction->setText(tr("&Save %1").arg(fName));
m_d->m_revertToSavedAction->setText(tr("Revert %1 to Saved").arg(fName));
QString quotedName;
if (!fName.isEmpty())
quotedName = '"' + fName + '"';
m_d->m_saveAsAction->setText(tr("Save %1 As...").arg(quotedName));
m_d->m_saveAction->setText(tr("&Save %1").arg(quotedName));
m_d->m_revertToSavedAction->setText(tr("Revert %1 to Saved").arg(quotedName));
m_d->m_closeCurrentEditorAction->setEnabled(curEditor != 0);
m_d->m_closeCurrentEditorAction->setText(tr("Close %1").arg(fName));
m_d->m_closeCurrentEditorAction->setText(tr("Close %1").arg(quotedName));
m_d->m_closeAllEditorsAction->setEnabled(openedCount > 0);
m_d->m_gotoNextDocHistoryAction->setEnabled(m_d->m_editorHistory.count() > 0);
......
......@@ -419,11 +419,11 @@ EditorView::EditorView(EditorModel *model, QWidget *parent) :
m_statusWidgetButton->setText(tr("Placeholder"));
hbox->addWidget(m_statusWidgetButton);
m_statusHLine->setVisible(false);
m_statusWidget->setVisible(false);
tl->addWidget(m_statusHLine);
tl->addWidget(m_statusWidget);
}
}
EditorView::~EditorView()
......
......@@ -602,22 +602,6 @@ CPPEditor::Link CPPEditor::findLinkAt(const QTextCursor &cursor,
if (!doc)
return link;
// Handle include directives
const unsigned lineno = cursor.blockNumber() + 1;
foreach (const Document::Include &incl, doc->includes()) {
if (incl.line() == lineno && incl.resolved()) {
link.fileName = incl.fileName();
link.pos = cursor.block().position();
link.length = cursor.block().length();
return link;
}
}
// Find the last symbol up to the cursor position
Symbol *lastSymbol = doc->findSymbolAt(line, column);
if (!lastSymbol)
return link;
QTextCursor tc = cursor;
static TokenUnderCursor tokenUnderCursor;
......@@ -625,14 +609,27 @@ CPPEditor::Link CPPEditor::findLinkAt(const QTextCursor &cursor,
QTextBlock block;
const SimpleToken tk = tokenUnderCursor(tc, &block);
if (tk.isLiteral() || tk.isComment()) {
// Drop out if we're at a number, string or comment
return link;
// Handle include directives
if (tk.is(T_STRING_LITERAL) || tk.is(T_ANGLE_STRING_LITERAL)) {
const unsigned lineno = cursor.blockNumber() + 1;
foreach (const Document::Include &incl, doc->includes()) {
if (incl.line() == lineno && incl.resolved()) {
link.fileName = incl.fileName();
link.pos = cursor.block().position() + tk.position() + 1;
link.length = tk.length() - 2;
return link;
}
}
}
if (tk.isNot(T_IDENTIFIER))
return link;
// Find the last symbol up to the cursor position
Symbol *lastSymbol = doc->findSymbolAt(line, column);
if (!lastSymbol)
return link;
const int nameStart = tk.position();
const int nameLength = tk.length();
const int endOfName = nameStart + nameLength;
......@@ -668,7 +665,7 @@ CPPEditor::Link CPPEditor::findLinkAt(const QTextCursor &cursor,
def = findDefinition(symbol);
link = linkToSymbol(def ? def : symbol);
link.pos = nameStart;
link.pos = block.position() + nameStart;
link.length = nameLength;
return link;
......
......@@ -383,9 +383,9 @@ void FunctionArgumentWidget::updateHintText()
const QDesktopWidget *desktop = QApplication::desktop();
#ifdef Q_OS_MAC
const QRect screen = desktop->availableGeometry(desktop->screenNumber(m_popupFrame));
const QRect screen = desktop->availableGeometry(desktop->screenNumber(m_editor->widget()));
#else
const QRect screen = desktop->screenGeometry(desktop->screenNumber(m_popupFrame));
const QRect screen = desktop->screenGeometry(desktop->screenNumber(m_editor->widget()));
#endif
const QSize sz = m_popupFrame->sizeHint();
......
......@@ -314,6 +314,10 @@ DebuggerSettings *theDebuggerSettings()
item->setDefaultValue(20);
instance->insertItem(MaximalStackDepth, item);
item = new SavedAction(instance);
item->setText(QObject::tr("Reload full stack"));
instance->insertItem(ExpandStack, item);
item = new SavedAction(instance);
item->setText(QObject::tr("Execute line"));
instance->insertItem(ExecuteCommand, item);
......
......@@ -79,6 +79,7 @@ enum DebuggerActionCode
// Stack
MaximalStackDepth,
ExpandStack,
// Watchers & Locals
WatchExpression,
......
......@@ -148,8 +148,7 @@ extern IDebuggerEngine *createWinEngine(DebuggerManager *)
#endif
extern IDebuggerEngine *createScriptEngine(DebuggerManager *parent);
DebuggerManager::DebuggerManager() :
m_attachCoreAction(0)
DebuggerManager::DebuggerManager()
{
init();
}
......@@ -294,11 +293,9 @@ void DebuggerManager::init()
m_attachExternalAction = new QAction(this);
m_attachExternalAction->setText(tr("Attach to Running External Application..."));
#ifndef Q_OS_WIN
m_attachCoreAction = new QAction(this);
m_attachCoreAction->setText(tr("Attach to Core..."));
connect(m_attachCoreAction, SIGNAL(triggered()), this, SLOT(attachCore()));
#endif
m_continueAction = new QAction(this);
m_continueAction->setText(tr("Continue"));
......@@ -1172,7 +1169,7 @@ void DebuggerManager::setStatus(int status)
if (status == m_status)
return;
if (!isAllowedTransition(m_status, status)) {
if (0 && !isAllowedTransition(m_status, status)) {
const QString msg = QString::fromLatin1("%1: UNEXPECTED TRANSITION: %2 -> %3").
arg(QLatin1String(Q_FUNC_INFO), QLatin1String(stateName(m_status)), QLatin1String(stateName(status)));
qWarning("%s", qPrintable(msg));
......@@ -1193,8 +1190,11 @@ void DebuggerManager::setStatus(int status)
m_startExternalAction->setEnabled(!started && !starting);
m_attachExternalAction->setEnabled(!started && !starting);
if (m_attachCoreAction)
m_attachCoreAction->setEnabled(!started && !starting);
#ifdef Q_OS_WIN
m_attachCoreAction->setEnabled(false);
#else
m_attachCoreAction->setEnabled(!started && !starting);
#endif
m_watchAction->setEnabled(ready);
m_breakAction->setEnabled(true);
......@@ -1372,7 +1372,7 @@ void DebuggerManager::disassemblerDockToggled(bool on)
//////////////////////////////////////////////////////////////////////
//
// Sourec files specific stuff
// Source files specific stuff
//
//////////////////////////////////////////////////////////////////////
......@@ -1449,4 +1449,19 @@ void DebuggerManager::reloadRegisters()
}
//////////////////////////////////////////////////////////////////////
//
// Testing
//
//////////////////////////////////////////////////////////////////////
void DebuggerManager::runTest(const QString &fileName)
{
m_executable = fileName;
m_processArgs = QStringList() << "--run-debuggee";
m_workingDir = QString();
if (!startNewDebugger(StartInternal))
emit debuggingFinished();
}
#include "debuggermanager.moc"
......@@ -341,6 +341,7 @@ public:
private:
void init();
void setDebuggerType(DebuggerType type);
void runTest(const QString &fileName);
QDockWidget *createDockForWidget(QWidget *widget);
Q_SLOT void createNewDock(QWidget *widget);
......
......@@ -796,6 +796,11 @@ bool DebuggerPlugin::initialize(const QStringList &arguments, QString *errorMess
void DebuggerPlugin::extensionsInitialized()
{
// time gdb -i mi -ex 'debuggerplugin.cpp:800' -ex r -ex q bin/qtcreator.bin
QByteArray env = qgetenv("QTC_DEBUGGER_TEST");
//qDebug() << "EXTENSIONS INITIALIZED:" << env;
if (!env.isEmpty())
m_manager->runTest(QString::fromLocal8Bit(env));
}
/*! Activates the previous mode when the current mode is the debug mode. */
......
......@@ -230,6 +230,9 @@ void GdbEngine::initializeConnections()
this, SLOT(reloadRegisters()));
connect(theDebuggerAction(FormatNatural), SIGNAL(triggered()),
this, SLOT(reloadRegisters()));
connect(theDebuggerAction(ExpandStack), SIGNAL(triggered()),
this, SLOT(reloadFullStack()));
}
void GdbEngine::initializeVariables()
......@@ -373,16 +376,18 @@ void GdbEngine::handleResponse(const QByteArray &buff)
GdbMi record;
while (from != to) {
if (*from != ',') {
qDebug() << "MALFORMED ASYNC OUTPUT" << from;
return;
}
++from; // skip ','
GdbMi data;
data.parseResultOrValue(from, to);
if (data.isValid()) {
//qDebug() << "parsed response: " << data.toString();
record.m_children += data;
if (*from == ',') {
++from; // skip ','
data.parseResultOrValue(from, to);
if (data.isValid()) {
//qDebug() << "parsed response: " << data.toString();
record.m_children += data;
record.m_type = GdbMi::Tuple;
}
} else {
// happens on archer where we get
// 23^running <NL> *running,thread-id="all" <NL> (gdb)
record.m_type = GdbMi::Tuple;
}
}
......@@ -395,6 +400,10 @@ void GdbEngine::handleResponse(const QByteArray &buff)
// target-name="/usr/lib/libdrm.so.2",
// host-name="/usr/lib/libdrm.so.2",
// symbols-loaded="0"
} else if (asyncClass == "library-unloaded") {
// Archer has 'id="/usr/lib/libdrm.so.2",
// target-name="/usr/lib/libdrm.so.2",
// host-name="/usr/lib/libdrm.so.2"
} else if (asyncClass == "thread-group-created") {
// Archer has "{id="28902"}"
} else if (asyncClass == "thread-created") {
......@@ -403,6 +412,8 @@ void GdbEngine::handleResponse(const QByteArray &buff)
// Archer has "{id="28902"}"
} else if (asyncClass == "thread-exited") {
//"{id="1",group-id="28902"}"
} else if (asyncClass == "thread-selected") {
//"{id="2"}"
#ifdef Q_OS_MAC
} else if (asyncClass == "shlibs-updated") {
// MAC announces updated libs
......@@ -473,14 +484,16 @@ void GdbEngine::handleResponse(const QByteArray &buff)
from = inner;
if (from != to) {
if (*from != ',') {
qDebug() << "MALFORMED RESULT OUTPUT" << from;
return;
if (*from == ',') {
++from;
record.data.parseTuple_helper(from, to);
record.data.m_type = GdbMi::Tuple;
record.data.m_name = "data";
} else {
// Archer has this
record.data.m_type = GdbMi::Tuple;
record.data.m_name = "data";
}
++from;
record.data.parseTuple_helper(from, to);
record.data.m_type = GdbMi::Tuple;
record.data.m_name = "data";
}
//qDebug() << "\nLOG STREAM:" + m_pendingLogStreamOutput;
......@@ -803,7 +816,7 @@ void GdbEngine::handleResult(const GdbResultRecord & record, int type,
break;
case StackListFrames:
handleStackListFrames(record);
handleStackListFrames(record, cookie.toBool());
break;
case StackListThreads:
handleStackListThreads(record, cookie.toInt());
......@@ -1301,12 +1314,18 @@ void GdbEngine::handleAsyncOutput(const GdbMi &data)
#endif
}
void GdbEngine::reloadFullStack()
{
QString cmd = "-stack-list-frames";
sendSynchronizedCommand(cmd, StackListFrames, true);
}
void GdbEngine::reloadStack()
{
QString cmd = "-stack-list-frames";
if (int stackDepth = theDebuggerAction(MaximalStackDepth)->value().toInt())
cmd += " 0 " + QString::number(stackDepth);
sendSynchronizedCommand(cmd, StackListFrames);
sendSynchronizedCommand(cmd, StackListFrames, false);
}
void GdbEngine::handleAsyncOutput2(const GdbMi &data)
......@@ -2450,7 +2469,7 @@ void GdbEngine::handleStackSelectThread(const GdbResultRecord &record, int)
}
void GdbEngine::handleStackListFrames(const GdbResultRecord &record)
void GdbEngine::handleStackListFrames(const GdbResultRecord &record, bool isFull)
{
QList<StackFrame> stackFrames;
......@@ -2501,30 +2520,11 @@ void GdbEngine::handleStackListFrames(const GdbResultRecord &record)
topFrame = i;
}
if (n >= theDebuggerAction(MaximalStackDepth)->value().toInt()) {
StackFrame frame(n);
frame.file = "...";
frame.function = "...";
frame.from = "...";
frame.line = 0;
frame.address = "...";
stackFrames.append(frame);
}
qq->stackHandler()->setFrames(stackFrames);
bool canExpand = !isFull
&& (n >= theDebuggerAction(MaximalStackDepth)->value().toInt());
theDebuggerAction(ExpandStack)->setEnabled(canExpand);
qq->stackHandler()->setFrames(stackFrames, canExpand);
#if 0
if (0 && topFrame != -1) {
// updates of locals already triggered early
const StackFrame &frame = qq->stackHandler()->currentFrame();
if (frame.isUsable())
q->gotoLocation(frame.file, frame.line, true);
else
qDebug() << "FULL NAME NOT USABLE 0: " << frame.file;
} else {
activateFrame(topFrame);
}
#else
if (topFrame != -1) {
// updates of locals already triggered early
const StackFrame &frame = qq->stackHandler()->currentFrame();
......@@ -2533,7 +2533,6 @@ void GdbEngine::handleStackListFrames(const GdbResultRecord &record)
else
qDebug() << "FULL NAME NOT USABLE 0: " << frame.file << topFrame;
}
#endif
}
void GdbEngine::selectThread(int index)
......@@ -2562,6 +2561,10 @@ void GdbEngine::activateFrame(int frameIndex)
//qDebug() << "ACTIVATE FRAME: " << frameIndex << oldIndex
// << stackHandler->currentIndex();
if (frameIndex == stackHandler->stackSize()) {
reloadFullStack();
return;
}
QTC_ASSERT(frameIndex < stackHandler->stackSize(), return);
if (oldIndex != frameIndex) {
......
......@@ -277,10 +277,11 @@ private:
//
// Stack specific stuff
//
void handleStackListFrames(const GdbResultRecord &record);
void handleStackListFrames(const GdbResultRecord &record, bool isFull);
void handleStackSelectThread(const GdbResultRecord &record, int cookie);
void handleStackListThreads(const GdbResultRecord &record, int cookie);
void reloadStack();
Q_SLOT void reloadStack();
Q_SLOT void reloadFullStack();
//
......
......@@ -115,18 +115,18 @@ void GdbMi::parseValue(const char *&from, const char *to)
{
//qDebug() << "parseValue: " << QByteArray::fromUtf16(from, to - from);
switch (*from) {
case '{':
parseTuple(from, to);
break;
case '[':
parseList(from, to);
break;
case '"':
m_type = Const;
m_data = parseCString(from, to);
break;
default:
break;
case '{':
parseTuple(from, to);
break;
case '[':
parseList(from, to);
break;
case '"':
m_type = Const;
m_data = parseCString(from, to);
break;
default:
break;
}
}
......@@ -211,52 +211,53 @@ void GdbMi::dumpChildren(QByteArray * str, bool multiline, int indent) const
}
}
static QByteArray escaped(QByteArray ba)
{
ba.replace("\"", "\\\"");
return ba;
}
QByteArray GdbMi::toString(bool multiline, int indent) const
{
QByteArray result;
switch (m_type) {
case Invalid:
if (multiline) {
result += ind(indent) + "Invalid\n";
} else {
result += "Invalid";
}
break;
case Const:
if (!m_name.isEmpty())
result += m_name + "=";
if (multiline) {
result += "\"" + m_data + "\"";
} else {
result += "\"" + m_data + "\"";
}
break;
case Tuple:
if (!m_name.isEmpty())
result += m_name + "=";
if (multiline) {
result += "{\n";
dumpChildren(&result, multiline, indent + 1);
result += '\n' + ind(indent) + "}";
} else {
result += "{";
dumpChildren(&result, multiline, indent + 1);
result += "}";
}
break;
case List:
if (!m_name.isEmpty())
result += m_name + "=";
if (multiline) {
result += "[\n";
dumpChildren(&result, multiline, indent + 1);
result += "]";
} else {
result += "[";
dumpChildren(&result, multiline, indent + 1);
result += '\n' + ind(indent) + "]";
}
break;
case Invalid:
if (multiline)
result += ind(indent) + "Invalid\n";
else
result += "Invalid";
break;
case Const:
if (!m_name.isEmpty())
result += m_name + "=";
result += "\"" + escaped(m_data) + "\"";
break;
case Tuple:
if (!m_name.isEmpty())
result += m_name + "=";
if (multiline) {
result += "{\n";
dumpChildren(&result, multiline, indent + 1);
result += '\n' + ind(indent) + "}";
} else {
result += "{";
dumpChildren(&result, multiline, indent + 1);
result += "}";
}
break;
case List:
if (!m_name.isEmpty())
result += m_name + "=";
if (multiline) {
result += "[\n";
dumpChildren(&result, multiline, indent + 1);
result += '\n' + ind(indent) + "]";
} else {
result += "[";
dumpChildren(&result, multiline, indent + 1);
result += "]";
}
break;
}
return result;
}
......@@ -319,152 +320,5 @@ QByteArray GdbResultRecord::toString() const
return result;
}
//////////////////////////////////////////////////////////////////////////////////