Merge remote-tracking branch 'origin/4.2'

Conflicts:
	qbs/modules/qtc/qtc.qbs
	qtcreator.pri
	src/shared/qbs

Change-Id: I5050baa31f4a892d00cd6f7e088d1b597921474d
This commit is contained in:
Eike Ziller
2016-12-05 10:55:35 +01:00
35 changed files with 452 additions and 337 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

After

Width:  |  Height:  |  Size: 18 KiB

BIN
doc/images/navigator.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 434 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 35 KiB

After

Width:  |  Height:  |  Size: 36 KiB

BIN
doc/images/statistics.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 258 B

View File

@@ -236,7 +236,7 @@
To enable the debugger to step into the code and display the source code To enable the debugger to step into the code and display the source code
when using a copy of the source tree at a location different from the one when using a copy of the source tree at a location different from the one
at which the libraries where built, map the source paths to target paths: at which the libraries were built, map the source paths to target paths:
\list 1 \list 1

View File

@@ -160,9 +160,15 @@
{Options to Request or Suppress Warnings} or the GCC or Clang {Options to Request or Suppress Warnings} or the GCC or Clang
manual pages. manual pages.
\li To have Clang process pre-compiled headers, deselect the \li To process pre-compiled headers, deselect the
\uicontrol {Ignore pre-compiled headers} check box. \uicontrol {Ignore pre-compiled headers} check box.
\li To avoid out-of-memory crashes caused by indexing huge source files
that are typically auto-generated by scripts or code, the size of
files to index is limited to 5MB by default. To adjust the limit,
edit the value for the \uicontrol {Do not index files greater than}
check box. To index all files, deselect the check box.
\endlist \endlist
*/ */

View File

@@ -83,8 +83,7 @@
To only show text changes, select \uicontrol {Ignore Whitespace}. To only show text changes, select \uicontrol {Ignore Whitespace}.
To expand the context for the changes, set the number of unchanged lines to To expand the context for the changes, set the number of unchanged lines to
show in \uicontrol {Context lines}. Set the value to -1 to show the whole show in \uicontrol {Context lines}.
file.
By default, the horizontal scroll bars in the left and right pane are By default, the horizontal scroll bars in the left and right pane are
synchronized. To use them independently of each other, select the synchronized. To use them independently of each other, select the

View File

@@ -91,10 +91,13 @@
To keep the selections in the diagram and the \uicontrol Structure view To keep the selections in the diagram and the \uicontrol Structure view
synchronized, select \uicontrol {Keep Synchronized}. synchronized, select \uicontrol {Keep Synchronized}.
To zoom into diagrams, press \key Ctrl++ or press \key Ctrl and roll the To zoom into diagrams, select \uicontrol Tools > \uicontrol {Model Editor} >
mouse wheel up. To zoom out of diagrams, press \key Ctrl+- or press \uicontrol {Zoom In}, press \key Ctrl++, or press \key Ctrl and roll the
\key Ctrl and roll the mouse wheel down. To reset the diagram size to 100%, mouse wheel up. To zoom out of diagrams, select \uicontrol Tools >
select \key Ctrl+0. \uicontrol {Model Editor} > \uicontrol {Zoom Out}, press \key Ctrl+-, or
press \key Ctrl and roll the mouse wheel down. To reset the diagram size to
100%, select \uicontrol Tools > \uicontrol {Model Editor} > \uicontrol
{Reset Zoom} or press \key Ctrl+0.
To print diagrams, press \key Ctrl+C when no elements are selected in To print diagrams, press \key Ctrl+C when no elements are selected in
the editor to copy all elements to the clipboard by using 300 dpi. Then the editor to copy all elements to the clipboard by using 300 dpi. Then

View File

@@ -128,6 +128,9 @@
\li Select \uicontrol {Show command lines} to print actual command lines \li Select \uicontrol {Show command lines} to print actual command lines
to the compile output pane instead of high-level descriptions. to the compile output pane instead of high-level descriptions.
\li Select \uicontrol {Force probes} to force re-execution of the
configure scripts of \l{https://doc.qt.io/qbs/probe-item.html}{Probes}.
\li Select \uicontrol {Install} to copy artifacts to their install location \li Select \uicontrol {Install} to copy artifacts to their install location
after building them. This option is enabled by default. after building them. This option is enabled by default.

View File

@@ -41,23 +41,29 @@
build and run settings for the development targets might be set up build and run settings for the development targets might be set up
automatically in \QC. automatically in \QC.
To view and modify the settings for currently open projects, switch to the When you open a project for the first time, the
\uicontrol Projects mode by pressing \key Ctrl+5. \uicontrol {Configure Projects} view is displayed to let you select a set of
\l{glossary-buildandrun-kit}{kits} that you want to use to build and run
your project. At least one kit must be active for you to be able to build
and run the project. For more information about selecting the initial kit,
see \l{Opening Projects}.
You can select build and run \l{glossary-buildandrun-kit}{kits} for the To maintain the list of active kits for a currently open project, switch to
open projects and use the \uicontrol Build menu commands to build, deploy, and the \uicontrol Projects mode by pressing \key Ctrl+5.
run projects.
\section1 Selecting Kits \section1 Activating Kits for a Project
All kits compatible with your project are listed in the
\uicontrol {Build & Run} section of the sidebar. To activate one or more
disabled kits, click them.
\image qtcreator-project-kits.png \image qtcreator-project-kits.png
To enable kits for the project, click them in \uicontrol {Build & Run}. The The list displays kits that are configured in \uicontrol Tools >
list displays kits that are configured in \uicontrol Tools >
\uicontrol Options > \uicontrol {Build & Run} > \uicontrol Kits. To modify \uicontrol Options > \uicontrol {Build & Run} > \uicontrol Kits. To modify
kit configuration or to add kits to the list, select kit configuration or to add kits to the list, right-click the sidebar to
\uicontrol {Manage Kits} in the context menu. For more information about open a context-menu, and then select \uicontrol {Manage Kits}. For more
managing kits, see \l{Adding Kits}. information about managing kits, see \l{Adding Kits}.
Each kit consists of a set of values that define one environment, such as a Each kit consists of a set of values that define one environment, such as a
device, compiler, and Qt version. For more information, see device, compiler, and Qt version. For more information, see
@@ -66,33 +72,22 @@
To copy the build and run settings for a kit to another kit, select To copy the build and run settings for a kit to another kit, select
\uicontrol {Copy Steps from Other Kit} in the context menu. \uicontrol {Copy Steps from Other Kit} in the context menu.
To disable a kit for the project, select \uicontrol {Disable Kit for Project} To deactivate a kit, select \uicontrol {Disable Kit for Project} in the
in the context menu. context menu.
\note Deactivating a kit removes all custom build and run settings for the
kit.
To import an existing build for the project, select To import an existing build for the project, select
\uicontrol {Import Existing Build} in the context menu. \uicontrol {Import Existing Build} in the context menu.
\section1 Specifying Settings \section1 Specifying Settings
The \uicontrol Projects mode displays one of the following views: To specify build or run settings for a kit, select \uicontrol Build or
\uicontrol Run below the kit. For more information, see
\l{Specifying Build Settings} and \l{Specifying Run Settings}.
\list In addition, you can modify the following global settings for each project:
\li \uicontrol {Build & Run} settings for each configured kit:
\list
\li \l{Specifying Build Settings}{Build}
\li \l{Specifying Run Settings}{Run}
\endlist
\note If you have not configured the project for building, the
\uicontrol {Build & Run} view is replaced by the
\l{Opening Projects}{Configure Projects} view.
\li \uicontrol {Project Settings} for each project:
\list \list
@@ -102,14 +97,14 @@
\li \l{Specifying Dependencies}{Dependencies} \li \l{Specifying Dependencies}{Dependencies}
\li \l{Parsing C++ Files with the Clang Code Model} (experimental) \li \l{Parsing C++ Files with the Clang Code Model}
{Clang Code Model} (experimental)
\li \l{Using Clang Static Analyzer}{Clang Static Analyzer} \li \l{Using Clang Static Analyzer}{Clang Static Analyzer}
\li \l{To-Do Entries}{To-Do} (experimental) \li \l{To-Do Entries}{To-Do} (experimental)
\endlist \endlist
\endlist
If you have multiple projects open in \QC, select the project to configure If you have multiple projects open in \QC, select the project to configure
in the list of projects. in the list of projects.

View File

@@ -114,7 +114,7 @@
\li \l{Using Layouts} \li \l{Using Layouts}
\li \l{Using Split Views} \li \l{Organizing Items}
\endlist \endlist
@@ -269,12 +269,29 @@
\uicontrol Layout > \uicontrol {Fill Width} in the context menu. To make the item as \uicontrol Layout > \uicontrol {Fill Width} in the context menu. To make the item as
high as possible, select \uicontrol {Fill Height}. high as possible, select \uicontrol {Fill Height}.
\section2 Using Split Views \section2 Organizing Items
From Qt 5.1, you can use the SplitView Qt Quick Control to arrange items From Qt 5.7, you can use the following \l{Qt Quick Controls 2} types to
horizontally or vertically organize items on screens:
with a draggable splitter between each item.
\list
\li \l [QtQuickControls2]{Frame} places a logical group of controls
within a visual frame.
\li \l [QtQuickControls2]{GroupBox}{Group Box} is used to lay out a
logical group of controls together, within a titled visual frame.
\li \l [QtQuickControls2]{Label} is a text label with inherited styling
and font.
\li \l [QtQuickControls2]{PageIndicator}{Page Indicator} indicates the
currently active page.
\li \l [QtQuickControls2]{Pane} provides a background matching with the
application style and theme.
\endlist
\section1 Using States \section1 Using States
@@ -382,62 +399,68 @@
\endlist \endlist
From Qt 5.1, you can also use the following Since Qt 5.7, you can also use the following \l{Qt Quick Controls 2} types
\l{Qt Quick Controls} to present or receive input from the user: to inform users about the progress of the application or to gather input
from the user:
\list \list
\li \l{Button} provides a push button that you can associate with an \li \l [QtQuickControls2]{BusyIndicator}{Busy Indicator} indicates
action. activity while content is being loaded.
\li CheckBox provides an option button that can be toggled on \li \l [QtQuickControls2]{Button} provides a push button that you can
(checked) or off (unchecked). associate with an action.
\li ComboBox provides a drop-down list. Add items to the combo box by \li \l [QtQuickControls2]{CheckBox}{Check Box} provides an option button
assigning it a ListModel, or a list of strings to the model that can be toggled on (checked) or off (unchecked).
property.
\li GroupBox provides a frame, a title on top, and place for various \li \l [QtQuickControls2]{CheckDelegate}{Check Delegate} presents an
other controls inside the frame. item delegate that can be toggled on (checked) or off (unchecked).
\li \l{Label} provides a text label that follows the font and color scheme \li \l [QtQuickControls2]{ComboBox}{Combo Box} is a combined button and
of the system. popup list that is populated by using a data model.
\li ProgressBar indicates the progress of an operation. \li \l [QtQuickControls2]{Dial} is a circular dial that is rotated to
set a value.
\li RadioButton provides an option button that can be switched on \li \l [QtQuickControls2]{ItemDelegate}{Item Delegate} is a standard
(checked) or off (unchecked). view item that can be used in various views and controls.
\li \l{Slider} \li \l [QtQuickControls2]{ProgressBar}{Progress Bar} indicates the
{Slider (Horizontal) and Slider (Vertical)} enable the user to move progress of an operation.
a slider handle along a horizontal or vertical groove and translate
the handle's position into a value within the specified range.
\li SpinBox enables the user to specify a value by clicking the up or \li \l [QtQuickControls2]{RadioButton}{Radio Button} provides an option
down buttons, by pressing up or down on the keyboard, or by entering button that can be switched on (checked) or off (unchecked).
a value in the box.
\omit \li \l [QtQuickControls2]{RadioDelegate}{Radio Delegate} presents an
Not visible in the item library in 3.2. item delegate that can be toggled on (checked) or off (unchecked).
\li StatusBar contains status information in your application. It
does not provide a layout of its own, but requires you to position
its contents, for instance by creating a \uicontrol {Row Layout}.
\endomit
\li TextArea displays multiple lines of editable formatted text. \li \l [QtQuickControls2]{Slider} selects a value by sliding a handle
along a track.
\li TextField displays a single line of editable plain text. \li \l [QtQuickControls2]{SpinBox}{Spin Box} enables the user to specify
a value by clicking the up or down buttons, by pressing up or down
on the keyboard, or by entering a value in the box.
\omit \li \l [QtQuickControls2]{Switch} is an option button that can be
Not visible in the item library in 3.2. toggled on or off.
\li ToolBar provides styling for ToolButton as well as other controls
that it can contain. However, it does not provide a layout of its
own, but requires you to position its contents, for instance by
creating a \uicontrol {Row Layout}.
\endomit
\li ToolButton provides a button that is functionally similar to \li \l [QtQuickControls2]{TextArea}{Text Area} displays multiple lines
\uicontrol Button, but that looks more suitable on a \uicontrol {Tool Bar}. of editable formatted text.
\li \l [QtQuickControls2]{TextField}{Text Field} displays a single line
of editable plain text.
\li \l [QtQuickControls2]{ToolBar}{Tool Bar} is a container of
application-wide and context sensitive actions and controls, such as
navigation buttons and search fields.
\li \l [QtQuickControls2]{ToolButton}{Tool Button} is a button
that is functionally similar to \uicontrol Button, but provides a
look that is more suitable for a \uicontrol {Tool Bar}.
\li \l [QtQuickControls2]{Tumbler} is a spinnable wheel of items that
can be selected.
\endlist \endlist

View File

@@ -65,12 +65,8 @@ def qdump__boost__shared_ptr(d, value):
d.check(weakcount >= 0) d.check(weakcount >= 0)
d.check(weakcount <= usecount) d.check(weakcount <= usecount)
d.check(usecount <= 10*1000*1000) d.check(usecount <= 10*1000*1000)
d.putItem(d.createValue(px, value.type[0]))
with Children(d): d.putBetterType(value.type)
short = d.putSubItem("data", d.createValue(px, value.type[0]))
d.putIntItem("weakcount", weakcount)
d.putIntItem("usecount", usecount)
d.putValue(short.value, short.encoding)
def qdump__boost__container__list(d, value): def qdump__boost__container__list(d, value):

View File

@@ -253,6 +253,9 @@ class DumperBase:
self.typesReported = {} self.typesReported = {}
self.typesToReport = {} self.typesToReport = {}
self.qtNamespaceToReport = None self.qtNamespaceToReport = None
self.qtCustomEventFunc = 0
self.qtCustomEventPltFunc = 0
self.qtPropertyFunc = 0
self.passExceptions = False self.passExceptions = False
self.isTesting = False self.isTesting = False
@@ -303,7 +306,7 @@ class DumperBase:
self.forceQtNamespace = int(args.get('forcens', '0')) self.forceQtNamespace = int(args.get('forcens', '0'))
self.passExceptions = int(args.get('passexceptions', '0')) self.passExceptions = int(args.get('passexceptions', '0'))
self.isTesting = int(args.get('testing', '0')) self.isTesting = int(args.get('testing', '0'))
self.showQObjectNames = int(args.get('qobjectnames', '0')) self.showQObjectNames = int(args.get('qobjectnames', '1'))
self.nativeMixed = int(args.get('nativemixed', '0')) self.nativeMixed = int(args.get('nativemixed', '0'))
self.autoDerefPointers = int(args.get('autoderef', '0')) self.autoDerefPointers = int(args.get('autoderef', '0'))
self.partialVariable = args.get('partialvar', '') self.partialVariable = args.get('partialvar', '')
@@ -790,6 +793,13 @@ class DumperBase:
self.putField('keyencoded', key.encoding) self.putField('keyencoded', key.encoding)
self.putValue(value.value, value.encoding) self.putValue(value.value, value.encoding)
def putEnumValue(self, value, vals):
ival = value.integer()
nice = vals.get(ival, None)
display = ('%d' % ival) if nice is None else ('%s (%d)' % (nice, ival))
self.putValue(display)
self.putNumChild(0)
def putCallItem(self, name, rettype, value, func, *args): def putCallItem(self, name, rettype, value, func, *args):
with SubItem(self, name): with SubItem(self, name):
try: try:
@@ -1366,11 +1376,13 @@ class DumperBase:
def putQObjectNameValue(self, value): def putQObjectNameValue(self, value):
try: try:
intSize = 4
ptrSize = self.ptrSize()
# dd = value['d_ptr']['d'] is just behind the vtable. # dd = value['d_ptr']['d'] is just behind the vtable.
(vtable, dd) = self.split('pp', value) (vtable, dd) = self.split('pp', value)
if not self.couldBeQObjectVTable(vtable):
return False
intSize = 4
ptrSize = self.ptrSize()
if self.qtVersion() < 0x050000: if self.qtVersion() < 0x050000:
# Size of QObjectData: 5 pointer + 2 int # Size of QObjectData: 5 pointer + 2 int
# - vtable # - vtable
@@ -1421,97 +1433,62 @@ class DumperBase:
except: except:
# warn('NO QOBJECT: %s' % value.type) # warn('NO QOBJECT: %s' % value.type)
pass return False
def canBePointer(self, p): def couldBePointer(self, p):
if self.ptrSize() == 4: if self.ptrSize() == 4:
return p > 100000 and (p & 0x3 == 0) return p > 100000 and (p & 0x3 == 0)
else: else:
return p > 100000 and (p & 0x7 == 0) and (p < 0x7fffffffffff) return p > 100000 and (p & 0x7 == 0) and (p < 0x7fffffffffff)
def canBeVTableEntry(self, p): def couldBeVTableEntry(self, p):
if self.ptrSize() == 4: if self.ptrSize() == 4:
return p > 100000 and (p & 0x1 == 0) return p > 100000 and (p & 0x1 == 0)
else: else:
return p > 100000 and (p & 0x1 == 0) and (p < 0x7fffffffffff) return p > 100000 and (p & 0x1 == 0) and (p < 0x7fffffffffff)
def couldBeQObject(self, objectPtr): def couldBeQObjectPointer(self, objectPtr):
try: try:
(vtablePtr, dd) = self.split('pp', objectPtr) vtablePtr, dd = self.split('pp', objectPtr)
except: except:
self.bump('nostruct-1') self.bump('nostruct-1')
return False return False
if not self.canBePointer(vtablePtr):
self.bump('vtable')
return False
if not self.canBePointer(dd):
self.bump('d_d_ptr')
return False
try: try:
metaObjectFunc, metaCastFunc, metaCallFunc = self.split('ppp', vtablePtr) dvtablePtr, qptr, parentPtr = self.split('ppp', dd)
except:
return False
# The first three entries are in a fairly rigid relationship defined
# by the Q_OBJECT macro.
if not self.canBeVTableEntry(metaObjectFunc):
return False
if not self.canBeVTableEntry(metaCastFunc):
return False
if not self.canBeVTableEntry(metaCallFunc):
return False
if metaCastFunc < metaObjectFunc or metaCastFunc > metaObjectFunc + 200:
# The metaObject implementation is just that:
# QObject::d_ptr->metaObject ? QObject::d_ptr->dynamicMetaObject()
# : &staticMetaObject;
# That should not exceed 200 bytes. Observed on x86_64 debug 72.
return False
if metaCallFunc < metaCastFunc or metaCallFunc > metaCastFunc + 200:
# if (!_clname) return nullptr;
# if (!strcmp(_clname, qt_meta_stringdata_Bar__TestObject.stringdata0))
# return static_cast<void*>(const_cast< TestObject*>(this));
# return QWidget::qt_metacast(_clname);
# That should not exceed 200 bytes. Observed on x86_64 debug 80.
return False
try:
(dvtablePtr, qptr, parentPtr, childrenDPtr, flags) \
= self.split('ppppI', dd)
except: except:
self.bump('nostruct-2') self.bump('nostruct-2')
return False return False
#warn('STRUCT DD: %s 0x%x' % (self.currentIName, qptr))
if not self.canBePointer(dvtablePtr):
self.bump('dvtable')
#warn('DVT: 0x%x' % dvtablePtr)
return False
# Check d_ptr.d.q_ptr == objectPtr # Check d_ptr.d.q_ptr == objectPtr
if qptr != objectPtr: if qptr != objectPtr:
#warn('QPTR: 0x%x 0x%x' % (qptr, objectPtr))
self.bump('q_ptr') self.bump('q_ptr')
return False return False
if parentPtr and not self.canBePointer(parentPtr):
#warn('PAREN')
self.bump('parent')
return False
if not self.canBePointer(childrenDPtr):
#warn('CHILD')
self.bump('children')
return False
#if flags >= 0x80: # Only 7 flags are defined
# warn('FLAGS: 0x%x %s' % (flags, self.currentIName))
# self.bump('flags')
# return False
#warn('OK')
#if dynMetaObjectPtr and not self.canBePointer(dynMetaObjectPtr):
# self.bump('dynmo')
# return False
self.bump('couldBeQObject') return self.couldBeQObjectVTable(vtablePtr)
return True
def couldBeQObjectVTable(self, vtablePtr):
try:
customEventFunc = self.extractPointer(vtablePtr + 9 * self.ptrSize())
except:
self.bump('nostruct-3')
return False
return customEventFunc in (self.qtCustomEventFunc, self.qtCustomEventPltFunc)
def extractQObjectProperty(objectPtr):
vtablePtr = self.extractPointer(objectPtr)
metaObjectFunc = self.extractPointer(vtablePtr)
cmd = '((void*(*)(void*))0x%x)((void*)0x%x)' % (metaObjectFunc, objectPtr)
try:
#warn('MO CMD: %s' % cmd)
res = self.parseAndEvaluate(cmd)
#warn('MO RES: %s' % res)
self.bump('successfulMetaObjectCall')
return res.pointer()
except:
self.bump('failedMetaObjectCall')
#warn('COULD NOT EXECUTE: %s' % cmd)
return 0
def extractMetaObjectPtr(self, objectPtr, typeobj): def extractMetaObjectPtr(self, objectPtr, typeobj):
""" objectPtr - address of *potential* instance of QObject derived class """ objectPtr - address of *potential* instance of QObject derived class
@@ -1521,7 +1498,7 @@ class DumperBase:
self.checkIntType(objectPtr) self.checkIntType(objectPtr)
def extractMetaObjectPtrFromAddress(): def extractMetaObjectPtrFromAddress():
return 0 #return 0
# FIXME: Calling 'works' but seems to impact memory contents(!) # FIXME: Calling 'works' but seems to impact memory contents(!)
# in relevant places. One symptom is that object name # in relevant places. One symptom is that object name
# contents 'vanishes' as the reported size of the string # contents 'vanishes' as the reported size of the string
@@ -1535,7 +1512,7 @@ class DumperBase:
res = self.parseAndEvaluate(cmd) res = self.parseAndEvaluate(cmd)
#warn('MO RES: %s' % res) #warn('MO RES: %s' % res)
self.bump('successfulMetaObjectCall') self.bump('successfulMetaObjectCall')
return toInteger(res) return res.pointer()
except: except:
self.bump('failedMetaObjectCall') self.bump('failedMetaObjectCall')
#warn('COULD NOT EXECUTE: %s' % cmd) #warn('COULD NOT EXECUTE: %s' % cmd)
@@ -1587,7 +1564,8 @@ class DumperBase:
# if base is not None and base != someTypeObj: # sanity check # if base is not None and base != someTypeObj: # sanity check
# result = extractStaticMetaObjectPtrFromType(base) # result = extractStaticMetaObjectPtrFromType(base)
self.knownStaticMetaObjects[someTypeName] = result if result:
self.knownStaticMetaObjects[someTypeName] = result
return result return result
@@ -1603,7 +1581,7 @@ class DumperBase:
#warn('CACHED RESULT: %s %s 0x%x' % (self.currentIName, typeName, result)) #warn('CACHED RESULT: %s %s 0x%x' % (self.currentIName, typeName, result))
return result return result
if not self.couldBeQObject(objectPtr): if not self.couldBeQObjectPointer(objectPtr):
self.bump('cannotBeQObject') self.bump('cannotBeQObject')
#warn('DOES NOT LOOK LIKE A QOBJECT: %s' % self.currentIName) #warn('DOES NOT LOOK LIKE A QOBJECT: %s' % self.currentIName)
return 0 return 0
@@ -1683,8 +1661,11 @@ class DumperBase:
self.putNumChild(0) self.putNumChild(0)
# This is called is when a QObject derived class is expanded # This is called is when a QObject derived class is expanded
def putQObjectGuts(self, qobject, metaObjectPtr): def tryPutQObjectGuts(self, value):
self.putQObjectGutsHelper(qobject, qobject.address(), -1, metaObjectPtr, 'QObject') metaObjectPtr = self.extractMetaObjectPtr(value.address(), value.type)
if metaObjectPtr:
self.putQObjectGutsHelper(value, value.address(),
-1, metaObjectPtr, 'QObject')
def metaString(self, metaObjectPtr, index, revision): def metaString(self, metaObjectPtr, index, revision):
ptrSize = self.ptrSize() ptrSize = self.ptrSize()
@@ -1787,7 +1768,7 @@ class DumperBase:
qobjectPtrType = self.createType('QObject') # FIXME. qobjectPtrType = self.createType('QObject') # FIXME.
with SubItem(self, '[parent]'): with SubItem(self, '[parent]'):
self.putField('sortgroup', 9) self.putField('sortgroup', 9)
self.putItem(self.createValue(dd + 2 * ptrSize, qobjectPtrType)) self.putItem(self.createValue(parentPtr, qobjectPtrType))
with SubItem(self, '[children]'): with SubItem(self, '[children]'):
self.putField('sortgroup', 8) self.putField('sortgroup', 8)
base = self.extractPointer(dd + 3 * ptrSize) # It's a QList<QObject *> base = self.extractPointer(dd + 3 * ptrSize) # It's a QList<QObject *>
@@ -1881,8 +1862,21 @@ class DumperBase:
if qobject: if qobject:
# LLDB doesn't like calling it on a derived class, possibly # LLDB doesn't like calling it on a derived class, possibly
# due to type information living in a different shared object. # due to type information living in a different shared object.
base = self.createValue(qobjectPtr, '@QObject') #base = self.createValue(qobjectPtr, '@QObject')
self.putCallItem(name, '@QVariant', base, 'property', '"' + name + '"') #warn("CALL FUNC: 0x%x" % self.qtPropertyFunc)
cmd = '((QVariant(*)(void*,char*))0x%x)((void*)0x%x,"%s")' \
% (self.qtPropertyFunc, qobjectPtr, name)
try:
#warn('PROP CMD: %s' % cmd)
res = self.parseAndEvaluate(cmd)
#warn('PROP RES: %s' % res)
except:
self.bump('failedMetaObjectCall')
putt(name, ' ')
continue
#warn('COULD NOT EXECUTE: %s' % cmd)
#self.putCallItem(name, '@QVariant', base, 'property', '"' + name + '"')
self.putSubItem(name, res)
else: else:
putt(name, ' ') putt(name, ' ')
@@ -2679,23 +2673,16 @@ class DumperBase:
self.putNumChild(1) self.putNumChild(1)
self.putEmptyValue() self.putEmptyValue()
#warn('STRUCT GUTS: %s ADDRESS: 0x%x ' % (value.name, value.address())) #warn('STRUCT GUTS: %s ADDRESS: 0x%x ' % (value.name, value.address()))
metaObjectPtr = self.extractMetaObjectPtr(value.address(), value.type)
if self.showQObjectNames: if self.showQObjectNames:
self.preping(self.currentIName) self.preping(self.currentIName)
metaObjectPtr = self.extractMetaObjectPtr(value.address(), value.type)
self.ping(self.currentIName)
if metaObjectPtr:
self.context = value
self.putQObjectNameValue(value) self.putQObjectNameValue(value)
#warn('STRUCT GUTS: %s MO: 0x%x ' % (self.currentIName, metaObjectPtr)) self.ping(self.currentIName)
if self.isExpanded(): if self.isExpanded():
self.putField('sortable', 1) self.putField('sortable', 1)
with Children(self, 1, childType=None): with Children(self, 1, childType=None):
self.putFields(value) self.putFields(value)
if not self.showQObjectNames: if self.showQObjectNames:
metaObjectPtr = self.extractMetaObjectPtr(value.address(), value.type) self.tryPutQObjectGuts(value)
if metaObjectPtr:
self.putQObjectGuts(value, metaObjectPtr)
def symbolAddress(self, symbolName): def symbolAddress(self, symbolName):
res = self.parseAndEvaluate('(size_t)&' + symbolName) res = self.parseAndEvaluate('(size_t)&' + symbolName)
@@ -3275,7 +3262,7 @@ class DumperBase:
except: except:
return None return None
#warn('VTBL: 0x%x' % vtbl) #warn('VTBL: 0x%x' % vtbl)
if not self.dumper.canBePointer(vtbl): if not self.dumper.couldBePointer(vtbl):
return None return None
return self.dumper.nativeDynamicTypeName(address, self) return self.dumper.nativeDynamicTypeName(address, self)

View File

@@ -1010,6 +1010,12 @@ class Dumper(DumperBase):
self.ping('qtNamespace') self.ping('qtNamespace')
return res return res
def findSymbol(self, symbolName):
try:
return toInteger(gdb.parse_and_eval("(size_t)&'%s'" % symbolName))
except:
return 0
def qtNamespaceX(self): def qtNamespaceX(self):
if not self.currentQtNamespaceGuess is None: if not self.currentQtNamespaceGuess is None:
return self.currentQtNamespaceGuess return self.currentQtNamespaceGuess
@@ -1039,6 +1045,24 @@ class Dumper(DumperBase):
except: except:
pass pass
lenns = len(ns)
strns = ('%d%s' % (lenns - 2, ns[:lenns - 2])) if lenns else ''
if lenns:
sym = '_ZN%s7QObject11customEventEPNS_6QEventE' % strns
else:
sym = '_ZN7QObject11customEventEP6QEvent'
self.qtCustomEventFunc = self.findSymbol(sym)
if lenns:
sym = '_ZN%s7QObject11customEventEPNS_6QEventE@plt' % strns
else:
sym = '_ZN7QObject11customEventEP6QEvent@plt'
self.qtCustomEventPltFunc = self.findSymbol(sym)
sym = '_ZNK7%sQObject8propertyEPKc' % strns
self.qtPropertyFunc = self.findSymbol(sym)
# This might be wrong, but we can't do better: We found # This might be wrong, but we can't do better: We found
# a libQt5Core and could not extract a namespace. # a libQt5Core and could not extract a namespace.
# The best guess is that there isn't any. # The best guess is that there isn't any.

View File

@@ -679,6 +679,15 @@ class Dumper(DumperBase):
qtVersion = 0x10000 * int(major) + 0x100 * int(minor) + int(patch) qtVersion = 0x10000 * int(major) + 0x100 * int(minor) + int(patch)
self.qtVersion = lambda: qtVersion self.qtVersion = lambda: qtVersion
funcs = self.target.FindFunctions('QObject::customEvent')
if len(funcs):
symbol = funcs[0].GetSymbol()
self.qtCustomEventFunc = symbol.GetStartAddress().GetLoadAddress(self.target)
funcs = self.target.FindFunctions('QObject::property')
if len(funcs):
symbol = funcs[0].GetSymbol()
self.qtPropertyFunc = symbol.GetStartAddress().GetLoadAddress(self.target)
return (qtNamespace, qtVersion) return (qtNamespace, qtVersion)
return ('', 0x50200) return ('', 0x50200)

View File

@@ -190,6 +190,34 @@ def qdump_X_QModelIndex(d, value):
d.putCallItem('parent', '@QModelIndex', value, 'parent') d.putCallItem('parent', '@QModelIndex', value, 'parent')
#gdb.execute('call free($mi)') #gdb.execute('call free($mi)')
def qdump__Qt__ItemDataRole(d, value):
d.putEnumValue(value, {
0 : "Qt::DisplayRole",
1 : "Qt::DecorationRole",
2 : "Qt::EditRole",
3 : "Qt::ToolTipRole",
4 : "Qt::StatusTipRole",
5 : "Qt::WhatsThisRole",
6 : "Qt::FontRole",
7 : "Qt::TextAlignmentRole",
# obsolete: 8 : "Qt::BackgroundColorRole",
8 : "Qt::BackgroundRole",
# obsolete: 9 : "Qt::TextColorRole",
9 : "Qt::ForegroundRole",
10 : "Qt::CheckStateRole",
11 : "Qt::AccessibleTextRole",
12 : "Qt::AccessibleDescriptionRole",
13 : "Qt::SizeHintRole",
14 : "Qt::InitialSortOrderRole",
# 27-31 Qt4 ItemDataRoles
27 : "Qt::DisplayPropertyRole",
28 : "Qt::DecorationPropertyRole",
29 : "Qt::ToolTipPropertyRole",
30 : "Qt::StatusTipPropertyRole",
31 : "Qt::WhatsThisPropertyRole",
0x100 : "Qt::UserRole"
})
def qdump__QStandardItemData(d, value): def qdump__QStandardItemData(d, value):
role, pad, val = value.split('{@Qt::ItemDataRole}@{QVariant}') role, pad, val = value.split('{@Qt::ItemDataRole}@{QVariant}')
d.putPairContents(role.value(), (role, val), 'role', 'value') d.putPairContents(role.value(), (role, val), 'role', 'value')
@@ -202,8 +230,9 @@ def qdump__QStandardItem(d, value):
if d.isExpanded(): if d.isExpanded():
with Children(d): with Children(d):
d.putSubItem('[model]', d.createValue(model, '@QStandardItemModel')) d.putSubItem('[model]', d.createValue(model, '@QStandardItemModel'))
d.putSubItem('[values]', d.createVectorItem(values, 'QStandardItemData')) d.putSubItem('[values]', d.createVectorItem(values, '@QStandardItemData'))
d.putSubItem('[children]', d.createVectorItem(children, '@QStandardItem*')) d.putSubItem('[children]', d.createVectorItem(children,
d.createPointerType(value.type)))
def qdump__QDate(d, value): def qdump__QDate(d, value):

View File

@@ -657,6 +657,9 @@ def qdump__std____weak_ptr(d, value):
def qdump__std__weak_ptr(d, value): def qdump__std__weak_ptr(d, value):
return qdump__std__shared_ptr(d, value) return qdump__std__shared_ptr(d, value)
def qdump__std____1__weak_ptr(d, value):
return qdump__std____1__shared_ptr(d, value)
def qdump__std__shared_ptr(d, value): def qdump__std__shared_ptr(d, value):
if d.isMsvcTarget(): if d.isMsvcTarget():
@@ -667,41 +670,27 @@ def qdump__std__shared_ptr(d, value):
if i.pointer() == 0: if i.pointer() == 0:
d.putValue("(null)") d.putValue("(null)")
d.putNumChild(0) d.putNumChild(0)
return else:
with Children(d): d.putItem(i.dereference())
short = d.putSubItem("data", i.dereference()) d.putBetterType(value.type)
if d.isMsvcTarget():
refcount = value["_Rep"]
d.putIntItem("usecount", refcount["_Uses"])
d.putIntItem("weakcount", refcount["_Weaks"])
else:
refcount = value["_M_refcount"]["_M_pi"]
d.putIntItem("usecount", refcount["_M_use_count"])
d.putIntItem("weakcount", refcount["_M_weak_count"])
d.putValue(short.value, short.encoding)
def qdump__std____1__shared_ptr(d, value): def qdump__std____1__shared_ptr(d, value):
i = value["__ptr_"] i = value["__ptr_"]
if i.pointer() == 0: if i.pointer() == 0:
d.putValue("(null)") d.putValue("(null)")
d.putNumChild(0) d.putNumChild(0)
return else:
with Children(d): d.putItem(i.dereference())
short = d.putSubItem("data", i.dereference()) d.putBetterType(value.type)
d.putFields(value["__cntrl_"].dereference())
#d.putIntItem("usecount", refcount["_M_use_count"])
#d.putIntItem("weakcount", refcount["_M_weak_count"])
d.putValue(short.value, short.encoding)
def qdump__std__unique_ptr(d, value): def qdump__std__unique_ptr(d, value):
p = d.extractPointer(value) p = d.extractPointer(value)
if p == 0: if p == 0:
d.putValue("(null)") d.putValue("(null)")
d.putNumChild(0) d.putNumChild(0)
return else:
with Children(d): d.putItem(d.createValue(p, value.type[0]))
short = d.putSubItem("data", d.createValue(p, value.type[0])) d.putBetterType(value.type)
d.putValue(short.value, short.encoding)
def qdump__std____1__unique_ptr(d, value): def qdump__std____1__unique_ptr(d, value):
qdump__std__unique_ptr(d, value) qdump__std__unique_ptr(d, value)
@@ -1002,6 +991,14 @@ def qdump__std____1__basic_string(d, value):
def qdump__wstring(d, value): def qdump__wstring(d, value):
qdump__std__wstring(d, value) qdump__std__wstring(d, value)
def qdump__std____1__once_flag(d, value):
qdump__std__once_flag(d, value)
def qdump__std__once_flag(d, value):
d.putItem(value[0])
d.putBetterType(value.type)
d.putPlainChildren(value)
def qdump____gnu_cxx__hash_set(d, value): def qdump____gnu_cxx__hash_set(d, value):
ht = value["_M_ht"] ht = value["_M_ht"]

View File

@@ -32,9 +32,14 @@
#include "stringutils.h" #include "stringutils.h"
#include "symbolgroupvalue.h" #include "symbolgroupvalue.h"
#include <map>
#include <algorithm>
constexpr bool debugPyValue = false; constexpr bool debugPyValue = false;
constexpr bool debuggingValueEnabled() { return debugPyValue || debugPyCdbextModule; } constexpr bool debuggingValueEnabled() { return debugPyValue || debugPyCdbextModule; }
static std::map<CIDebugSymbolGroup *, std::list<Value *>> valuesForSymbolGroup;
std::string getSymbolName(CIDebugSymbolGroup *sg, ULONG index) std::string getSymbolName(CIDebugSymbolGroup *sg, ULONG index)
{ {
ULONG size = 0; ULONG size = 0;
@@ -147,6 +152,21 @@ PyObject *value_Address(Value *self)
return Py_BuildValue("K", address); return Py_BuildValue("K", address);
} }
void indicesMoved(CIDebugSymbolGroup *symbolGroup, ULONG start, ULONG delta)
{
if (delta == 0)
return;
ULONG count;
if (FAILED(symbolGroup->GetNumberSymbols(&count)))
return;
if (count <= start)
return;
for (Value *val : valuesForSymbolGroup[symbolGroup]) {
if (val->m_index >= start && val->m_index + delta < count)
val->m_index += delta;
}
}
bool expandValue(Value *v) bool expandValue(Value *v)
{ {
DEBUG_SYMBOL_PARAMETERS params; DEBUG_SYMBOL_PARAMETERS params;
@@ -154,7 +174,15 @@ bool expandValue(Value *v)
return false; return false;
if (params.Flags & DEBUG_SYMBOL_EXPANDED) if (params.Flags & DEBUG_SYMBOL_EXPANDED)
return true; return true;
return SUCCEEDED(v->m_symbolGroup->ExpandSymbol(v->m_index, TRUE)); if (FAILED(v->m_symbolGroup->ExpandSymbol(v->m_index, TRUE)))
return false;
if (FAILED(v->m_symbolGroup->GetSymbolParameters(v->m_index, 1, &params)))
return false;
if (params.Flags & DEBUG_SYMBOL_EXPANDED) {
indicesMoved(v->m_symbolGroup, v->m_index + 1, params.SubElements);
return true;
}
return false;
} }
ULONG numberOfChildren(Value *v) ULONG numberOfChildren(Value *v)
@@ -310,8 +338,11 @@ PyObject *value_ChildFromIndex(Value *self, PyObject *args)
return createValue(self->m_index + index + 1, self->m_symbolGroup); return createValue(self->m_index + index + 1, self->m_symbolGroup);
} }
void value_Dealloc(Value *) void value_Dealloc(Value *v)
{ } {
auto values = valuesForSymbolGroup[v->m_symbolGroup];
std::remove(values.begin(), values.end(), v);
}
PyObject *value_New(PyTypeObject *type, PyObject *, PyObject *) PyObject *value_New(PyTypeObject *type, PyObject *, PyObject *)
{ {
@@ -339,6 +370,7 @@ PyObject *createValue(ULONG index, CIDebugSymbolGroup *symbolGroup)
if (value != NULL) { if (value != NULL) {
value->m_index = index; value->m_index = index;
value->m_symbolGroup = symbolGroup; value->m_symbolGroup = symbolGroup;
valuesForSymbolGroup[symbolGroup].push_back(value);
} }
return reinterpret_cast<PyObject*>(value); return reinterpret_cast<PyObject*>(value);
} }

View File

@@ -214,78 +214,112 @@ using decay_t = typename std::decay<T>::type;
template<typename T> template<typename T>
using result_of_t = typename std::result_of<T>::type; using result_of_t = typename std::result_of<T>::type;
// Result type of transform operation // abstraction to treat Container<T> and QStringList similarly
template<typename T>
struct ContainerType
{
template<template<typename> class Container, template<typename> class InputContainer, typename IT, typename Function> };
using ResultContainer = Container<decay_t<result_of_t<Function(IT)>>>;
} // anonymous // specialization for qt container T_Container<T_Type>
template<template<typename> class T_Container, typename T_Type>
struct ContainerType<T_Container<T_Type>>
{
template<class F, template<typename> class C = T_Container>
using ResultOfTransform = C<decay_t<result_of_t<F (T_Type)>>>;
template<class R>
using ResultOfTransformPMF = T_Container<decay_t<R>>;
};
// specialization for QStringList
template<>
struct ContainerType<QStringList> : ContainerType<QList<QString>>
{
};
}
// actual implementation of transform
template<typename C, // result container type
typename SC> // input container type
struct TransformImpl {
template <typename F>
Q_REQUIRED_RESULT
static C call(const SC &container, F function)
{
C result;
std::transform(container.begin(), container.end(),
inserter(result),
function);
return result;
}
template <typename R, typename S>
Q_REQUIRED_RESULT
static C call(const SC &container, R (S::*p)() const)
{
return call(container, std::mem_fn(p));
}
};
// same container type for input and output, e.g. transforming a QList<QString> into QList<int>
// or QStringList -> QList<>
template<typename C, // container
typename F>
Q_REQUIRED_RESULT
auto transform(const C &container, F function)
-> typename ContainerType<C>::template ResultOfTransform<F>
{
return TransformImpl<
typename ContainerType<C>::template ResultOfTransform<F>,
C
>::call(container, function);
}
// same container type for member function pointer
template<typename C,
typename R,
typename S>
Q_REQUIRED_RESULT
auto transform(const C &container, R (S::*p)() const)
->typename ContainerType<C>::template ResultOfTransformPMF<R>
{
return TransformImpl<
typename ContainerType<C>::template ResultOfTransformPMF<R>,
C
>::call(container, p);
}
// different container types for input and output, e.g. transforming a QList into a QSet // different container types for input and output, e.g. transforming a QList into a QSet
template<template<typename> class C, // result container type template<template<typename> class C, // result container type
template<typename> class SC, // input container type typename SC, // input container type
typename T, // input value type
typename F> // function type typename F> // function type
Q_REQUIRED_RESULT Q_REQUIRED_RESULT
auto transform(const SC<T> &container, F function) -> ResultContainer<C, SC, T, F> auto transform(const SC &container, F function)
-> typename ContainerType<SC>::template ResultOfTransform<F, C>
{ {
ResultContainer<C, SC, T, F> result; return TransformImpl<
std::transform(container.begin(), container.end(), typename ContainerType<SC>::template ResultOfTransform<F, C>,
inserter(result), SC
function); >::call(container, function);
return result;
} }
// different container types for input and output, e.g. transforming a QList into a QSet // different container types for input and output, e.g. transforming a QList into a QSet
// for member function pointers // for member function pointers
template<template<typename> class C, // result container type template<template<typename> class C, // result container type
template<typename> class SC, // input container type typename SC, // input container type
typename T, // input value type
typename R, typename R,
typename S> typename S>
Q_REQUIRED_RESULT Q_REQUIRED_RESULT
auto transform(const SC<T> &container, R (S::*p)() const) -> ResultContainer<C, SC, T, R(S::*)() const> auto transform(const SC &container, R (S::*p)() const)
-> C<decay_t<R>>
{ {
return Utils::transform<C, SC, T>(container, std::mem_fn(p)); return TransformImpl<
} C<decay_t<R>>,
SC
// same container type for input and output, e.g. transforming a QList<QString> into QList<int> >::call(container, p);
// or QStringList -> QList<>
template<template<typename> class C, // container
typename T, // container value type
typename F>
Q_REQUIRED_RESULT
auto transform(const C<T> &container, F function) -> ResultContainer<C, C, T, F>
{
return Utils::transform<C, C, T>(container, function);
}
// same container type for member function pointer
template<template<typename> class C, // container
typename T, // container value type
typename R,
typename S>
Q_REQUIRED_RESULT
auto transform(const C<T> &container, R (S::*p)() const) -> ResultContainer<C, C, T, R(S::*)() const>
{
return Utils::transform<C, C, T>(container, std::mem_fn(p));
}
// QStringList different containers
template<template<typename> class C, // result container type
typename F>
Q_REQUIRED_RESULT
auto transform(const QStringList &container, F function) -> ResultContainer<C, QList, QString, F>
{
return Utils::transform<C, QList, QString>(container, function);
}
// QStringList -> QList
template<typename F>
Q_REQUIRED_RESULT
auto transform(const QStringList &container, F function) -> ResultContainer<QList, QList, QString, F>
{
return Utils::transform<QList, QList, QString>(container, function);
} }
////////////////// //////////////////

View File

@@ -155,8 +155,6 @@ void TestCodeParser::updateTestTree()
return; return;
m_fullUpdatePostponed = false; m_fullUpdatePostponed = false;
emit aboutToPerformFullParse();
qCDebug(LOG) << "calling scanForTests (updateTestTree)"; qCDebug(LOG) << "calling scanForTests (updateTestTree)";
scanForTests(); scanForTests();
} }
@@ -199,6 +197,7 @@ void TestCodeParser::onStartupProjectChanged(ProjectExplorer::Project *project)
qCDebug(LOG) << "Canceling scanForTest (startup project changed)"; qCDebug(LOG) << "Canceling scanForTest (startup project changed)";
Core::ProgressManager::instance()->cancelTasks(Constants::TASK_PARSE); Core::ProgressManager::instance()->cancelTasks(Constants::TASK_PARSE);
} }
emit aboutToPerformFullParse();
if (project) if (project)
emitUpdateTestTree(); emitUpdateTestTree();
} }

View File

@@ -59,9 +59,14 @@ using namespace ProjectExplorer::Constants;
AutotoolsBuildConfiguration::AutotoolsBuildConfiguration(Target *parent) : AutotoolsBuildConfiguration::AutotoolsBuildConfiguration(Target *parent) :
BuildConfiguration(parent, Core::Id(AUTOTOOLS_BC_ID)) BuildConfiguration(parent, Core::Id(AUTOTOOLS_BC_ID))
{ {
// /<foobar> is used so the un-changed check in setBuildDirectory() works correctly. // /<foobar> is used so the un-changed check in setBuildDirectory() works correctly.
// The leading / is to avoid the relative the path expansion in BuildConfiguration::buildDirectory. // The leading / is to avoid the relative the path expansion in BuildConfiguration::buildDirectory.
BuildConfiguration::setBuildDirectory(Utils::FileName::fromString(QString::fromLatin1("/<foobar>"))); BuildConfiguration::setBuildDirectory(Utils::FileName::fromString(QString::fromLatin1("/<foobar>")));
connect(this, &BuildConfiguration::buildDirectoryChanged, this, [this] {
foreach (auto bs, stepList(BUILDSTEPS_BUILD)->allOfType<ConfigureStep>())
bs->notifyBuildDirectoryChanged();
});
} }
NamedWidget *AutotoolsBuildConfiguration::createConfigWidget() NamedWidget *AutotoolsBuildConfiguration::createConfigWidget()
@@ -222,12 +227,3 @@ BuildConfiguration::BuildType AutotoolsBuildConfiguration::buildType() const
// TODO: Should I return something different from Unknown? // TODO: Should I return something different from Unknown?
return Unknown; return Unknown;
} }
void AutotoolsBuildConfiguration::setBuildDirectory(const Utils::FileName &directory)
{
if (directory == buildDirectory())
return;
BuildConfiguration::setBuildDirectory(directory);
foreach (auto bs, stepList(BUILDSTEPS_BUILD)->allOfType<ConfigureStep>())
bs->notifyBuildDirectoryChanged();
}

View File

@@ -36,7 +36,6 @@ namespace Internal {
class AutotoolsTarget; class AutotoolsTarget;
class AutotoolsBuildConfigurationFactory; class AutotoolsBuildConfigurationFactory;
class AutotoolsBuildSettingsWidget;
class AutotoolsBuildConfiguration : public ProjectExplorer::BuildConfiguration class AutotoolsBuildConfiguration : public ProjectExplorer::BuildConfiguration
{ {
@@ -53,11 +52,6 @@ public:
protected: protected:
AutotoolsBuildConfiguration(ProjectExplorer::Target *parent, Core::Id id); AutotoolsBuildConfiguration(ProjectExplorer::Target *parent, Core::Id id);
AutotoolsBuildConfiguration(ProjectExplorer::Target *parent, AutotoolsBuildConfiguration *source); AutotoolsBuildConfiguration(ProjectExplorer::Target *parent, AutotoolsBuildConfiguration *source);
friend class AutotoolsBuildSettingsWidget;
private:
void setBuildDirectory(const Utils::FileName &directory) override;
}; };
class AutotoolsBuildConfigurationFactory : public ProjectExplorer::IBuildConfigurationFactory class AutotoolsBuildConfigurationFactory : public ProjectExplorer::IBuildConfigurationFactory

View File

@@ -411,8 +411,8 @@ void CMakeGeneratorKitInformation::fix(Kit *k)
void CMakeGeneratorKitInformation::upgrade(Kit *k) void CMakeGeneratorKitInformation::upgrade(Kit *k)
{ {
const QVariant value = k->value(GENERATOR_ID); const QVariant value = k->value(GENERATOR_ID);
GeneratorInfo info;
if (value.type() != QVariant::Map) { if (value.type() != QVariant::Map) {
GeneratorInfo info;
const QString fullName = value.toString(); const QString fullName = value.toString();
const int pos = fullName.indexOf(" - "); const int pos = fullName.indexOf(" - ");
if (pos >= 0) { if (pos >= 0) {

View File

@@ -102,12 +102,14 @@ void Find::destroy()
{ {
delete m_instance; delete m_instance;
m_instance = 0; m_instance = 0;
delete d->m_currentDocumentFind; if (d) {
delete d->m_findToolBar; delete d->m_currentDocumentFind;
delete d->m_findDialog; delete d->m_findToolBar;
ExtensionSystem::PluginManager::removeObject(d->m_searchResultWindow); delete d->m_findDialog;
delete d->m_searchResultWindow; ExtensionSystem::PluginManager::removeObject(d->m_searchResultWindow);
delete d; delete d->m_searchResultWindow;
delete d;
}
} }
Find *Find::instance() Find *Find::instance()

View File

@@ -257,15 +257,15 @@ DebuggerSettings::DebuggerSettings()
insertItem(ShowQtNamespace, item); insertItem(ShowQtNamespace, item);
item = new SavedAction(this); item = new SavedAction(this);
item->setSettingsKey(debugModeGroup, QLatin1String("ShowQObjectNames")); item->setSettingsKey(debugModeGroup, QLatin1String("ShowQObjectNames2"));
item->setText(tr("Show QObject names if available")); item->setText(tr("Show QObject names if available"));
item->setDialogText(tr("Show QObject names if available")); item->setDialogText(tr("Show QObject names if available"));
item->setToolTip(tr("<p>Displays the objectName property of QObject based items. " item->setToolTip(tr("<p>Displays the objectName property of QObject based items. "
"Note that this can negatively impact debugger performance " "Note that this can negatively impact debugger performance "
"even if no QObjects are present.")); "even if no QObjects are present."));
item->setCheckable(true); item->setCheckable(true);
item->setDefaultValue(false); item->setDefaultValue(true);
item->setValue(false); item->setValue(true);
insertItem(ShowQObjectNames, item); insertItem(ShowQObjectNames, item);
item = new SavedAction(this); item = new SavedAction(this);

View File

@@ -54,13 +54,6 @@ BuildConfiguration::BuildType NimBuildConfiguration::buildType() const
return BuildConfiguration::Unknown; return BuildConfiguration::Unknown;
} }
void NimBuildConfiguration::setBuildDirectory(const FileName &dir)
{
if (dir == buildDirectory())
return;
BuildConfiguration::setBuildDirectory(dir);
}
bool NimBuildConfiguration::fromMap(const QVariantMap &map) bool NimBuildConfiguration::fromMap(const QVariantMap &map)
{ {
if (!BuildConfiguration::fromMap(map)) if (!BuildConfiguration::fromMap(map))

View File

@@ -46,8 +46,6 @@ public:
ProjectExplorer::BuildConfiguration::BuildType buildType() const override; ProjectExplorer::BuildConfiguration::BuildType buildType() const override;
void setBuildDirectory(const Utils::FileName &dir) override;
bool fromMap(const QVariantMap &map) override; bool fromMap(const QVariantMap &map) override;
QVariantMap toMap() const override; QVariantMap toMap() const override;

View File

@@ -122,6 +122,8 @@ Utils::FileName BuildConfiguration::rawBuildDirectory() const
void BuildConfiguration::setBuildDirectory(const Utils::FileName &dir) void BuildConfiguration::setBuildDirectory(const Utils::FileName &dir)
{ {
if (dir == m_buildDirectory)
return;
m_buildDirectory = dir; m_buildDirectory = dir;
emitBuildDirectoryChanged(); emitBuildDirectoryChanged();
} }

View File

@@ -50,6 +50,7 @@ public:
Utils::FileName buildDirectory() const; Utils::FileName buildDirectory() const;
Utils::FileName rawBuildDirectory() const; Utils::FileName rawBuildDirectory() const;
void setBuildDirectory(const Utils::FileName &dir);
virtual NamedWidget *createConfigWidget() = 0; virtual NamedWidget *createConfigWidget() = 0;
virtual QList<NamedWidget *> createSubConfigWidgets(); virtual QList<NamedWidget *> createSubConfigWidgets();
@@ -96,7 +97,6 @@ protected:
BuildConfiguration(Target *target, Core::Id id); BuildConfiguration(Target *target, Core::Id id);
BuildConfiguration(Target *target, BuildConfiguration *source); BuildConfiguration(Target *target, BuildConfiguration *source);
virtual void setBuildDirectory(const Utils::FileName &dir);
void cloneSteps(BuildConfiguration *source); void cloneSteps(BuildConfiguration *source);
void emitEnvironmentChanged(); void emitEnvironmentChanged();

View File

@@ -333,11 +333,11 @@ public:
QAction *m_projectSelectorActionQuick; QAction *m_projectSelectorActionQuick;
QAction *m_runSubProject; QAction *m_runSubProject;
ProjectWindow *m_proWindow; ProjectWindow *m_proWindow = nullptr;
QString m_sessionToRestoreAtStartup; QString m_sessionToRestoreAtStartup;
QStringList m_profileMimeTypes; QStringList m_profileMimeTypes;
AppOutputPane *m_outputPane; AppOutputPane *m_outputPane = nullptr;
QList<QPair<QString, QString> > m_recentProjects; // pair of filename, displayname QList<QPair<QString, QString> > m_recentProjects; // pair of filename, displayname
static const int m_maxRecentProjects = 25; static const int m_maxRecentProjects = 25;

View File

@@ -102,6 +102,8 @@ enum { debug = 0 };
QmakeBuildConfiguration::QmakeBuildConfiguration(Target *target) QmakeBuildConfiguration::QmakeBuildConfiguration(Target *target)
: QmakeBuildConfiguration(target, Core::Id(QMAKE_BC_ID)) : QmakeBuildConfiguration(target, Core::Id(QMAKE_BC_ID))
{ {
connect(this, &BuildConfiguration::buildDirectoryChanged,
this, &QmakeBuildConfiguration::emitProFileEvaluateNeeded);
} }
QmakeBuildConfiguration::QmakeBuildConfiguration(Target *target, Core::Id id) : QmakeBuildConfiguration::QmakeBuildConfiguration(Target *target, Core::Id id) :
@@ -223,14 +225,6 @@ bool QmakeBuildConfiguration::isShadowBuild() const
return buildDirectory() != target()->project()->projectDirectory(); return buildDirectory() != target()->project()->projectDirectory();
} }
void QmakeBuildConfiguration::setBuildDirectory(const FileName &directory)
{
if (directory == buildDirectory())
return;
BuildConfiguration::setBuildDirectory(directory);
emitProFileEvaluateNeeded();
}
QString QmakeBuildConfiguration::makefile() const QString QmakeBuildConfiguration::makefile() const
{ {
return static_cast<QmakeProject *>(target()->project())->rootProjectNode()->makefile(); return static_cast<QmakeProject *>(target()->project())->rootProjectNode()->makefile();

View File

@@ -116,7 +116,6 @@ protected:
QmakeBuildConfiguration(ProjectExplorer::Target *target, QmakeBuildConfiguration *source); QmakeBuildConfiguration(ProjectExplorer::Target *target, QmakeBuildConfiguration *source);
QmakeBuildConfiguration(ProjectExplorer::Target *target, Core::Id id); QmakeBuildConfiguration(ProjectExplorer::Target *target, Core::Id id);
bool fromMap(const QVariantMap &map) override; bool fromMap(const QVariantMap &map) override;
void setBuildDirectory(const Utils::FileName &directory) override;
private: private:
void ctor(); void ctor();

View File

@@ -3398,6 +3398,14 @@ void tst_Dumpers::dumper_data()
"{\n" "{\n"
" void run()\n" " void run()\n"
" {\n" " {\n"
" auto mo = &QThread::metaObject;\n"
" auto mc = &QThread::qt_metacast;\n"
" auto p0 = (*(void***)this)[0]; unused(&p0);\n"
" auto p1 = (*(void***)this)[1]; unused(&p1);\n"
" auto p2 = (*(void***)this)[2]; unused(&p2);\n"
" auto p3 = (*(void***)this)[3]; unused(&p3);\n"
" auto p4 = (*(void***)this)[4]; unused(&p4);\n"
" auto p5 = (*(void***)this)[5]; unused(&p5);\n"
" if (m_id == 3) {\n" " if (m_id == 3) {\n"
" BREAK;\n" " BREAK;\n"
" }\n" " }\n"
@@ -4375,15 +4383,16 @@ void tst_Dumpers::dumper_data()
+ MacLibCppProfile() + MacLibCppProfile()
+ Check("p0", "(null)", "std::unique_ptr<int, std::default_delete<int> >") + Check("p0", "(null)", "std::unique_ptr<int, std::default_delete<int> >")
+ Check("p1", "32", "std::unique_ptr<int, std::default_delete<int> >") + Check("p1", "32", "std::unique_ptr<int, std::default_delete<int> >")
+ Check("p1.data", "32", "int")
+ Check("p2", Pointer(), "std::unique_ptr<Foo, std::default_delete<Foo> >") + Check("p2", Pointer(), "std::unique_ptr<Foo, std::default_delete<Foo> >")
+ CheckType("p2.data", "Foo") + Check("p3", "\"ABC\"", "std::unique_ptr<std::string, std::default_delete<std::string> >");
+ Check("p3", "\"ABC\"", "std::unique_ptr<std::string, std::default_delete<std::string> >")
+ Check("p3.data", "\"ABC\"", "std::string"); QTest::newRow("StdOnce")
<< Data("#include <mutex>\n",
"std::once_flag x; unused(&x);\n")
+ Cxx11Profile()
+ Check("x", "0", "std::once_flag");
QTest::newRow("StdSharedPtr") QTest::newRow("StdSharedPtr")
@@ -4401,17 +4410,12 @@ void tst_Dumpers::dumper_data()
+ MacLibCppProfile() + MacLibCppProfile()
+ Check("pi", "32", "std::shared_ptr<int>") + Check("pi", "32", "std::shared_ptr<int>")
+ Check("pi.data", "32", "int")
+ Check("pf", Pointer(), "std::shared_ptr<Foo>") + Check("pf", Pointer(), "std::shared_ptr<Foo>")
+ CheckType("pf.data", "Foo")
+ Check("ps", "\"ABC\"", "std::shared_ptr<std::string>") + Check("ps", "\"ABC\"", "std::shared_ptr<std::string>")
+ Check("ps.data", "\"ABC\"", "std::string")
+ Check("wi", "32", "std::weak_ptr<int>") + Check("wi", "32", "std::weak_ptr<int>")
+ Check("wi.data", "32", "int")
+ Check("wf", Pointer(), "std::weak_ptr<Foo>") + Check("wf", Pointer(), "std::weak_ptr<Foo>")
+ CheckType("wf.data", "Foo")
+ Check("ws", "\"ABC\"", "std::weak_ptr<std::string>") + Check("ws", "\"ABC\"", "std::weak_ptr<std::string>")
+ Check("ws.data", "\"ABC\"", "std::string"); + Check("ps", "\"ABC\"", "std::shared_ptr<std::string>");
QTest::newRow("StdSharedPtr2") QTest::newRow("StdSharedPtr2")
<< Data("#include <memory>\n" << Data("#include <memory>\n"
@@ -4429,10 +4433,10 @@ void tst_Dumpers::dumper_data()
+ Check("inner.m_1", "0x1", "int *") + Check("inner.m_1", "0x1", "int *")
+ Check("inner.m_2", "0x2", "int *") + Check("inner.m_2", "0x2", "int *")
+ Check("inner.x", "3", "int") + Check("inner.x", "3", "int")
+ Check("a.data.m_0", "0x0", "int *") + Check("a.m_0", "0x0", "int *")
+ Check("a.data.m_1", "0x1", "int *") + Check("a.m_1", "0x1", "int *")
+ Check("a.data.m_2", "0x2", "int *") + Check("a.m_2", "0x2", "int *")
+ Check("a.data.x", "3", "int"); + Check("a.x", "3", "int");
QTest::newRow("StdSet") QTest::newRow("StdSet")
<< Data("#include <set>\n", << Data("#include <set>\n",
@@ -5587,13 +5591,9 @@ void tst_Dumpers::dumper_data()
+ Check("s", "(null)", "boost::shared_ptr<int>") + Check("s", "(null)", "boost::shared_ptr<int>")
+ Check("i", "43", "boost::shared_ptr<int>") + Check("i", "43", "boost::shared_ptr<int>")
+ Check("i.weakcount", "1", "int")
+ Check("i.usecount", "2", "int")
+ Check("i.data", "43", "int")
+ Check("j", "43", "boost::shared_ptr<int>") + Check("j", "43", "boost::shared_ptr<int>")
+ Check("sl", "<1 items>", " boost::shared_ptr<@QStringList>") + Check("sl", "<1 items>", " boost::shared_ptr<@QStringList>")
+ Check("sl.data", "<1 items>", "@QStringList") + Check("sl.0", "[0]", "\"HUH!\"", "@QString");
+ Check("sl.data.0", "[0]", "\"HUH!\"", "@QString");
QTest::newRow("BoostGregorianDate") QTest::newRow("BoostGregorianDate")
@@ -6389,7 +6389,8 @@ void tst_Dumpers::dumper_data()
" root->appendRow(item);\n" " root->appendRow(item);\n"
"}\n") "}\n")
+ GuiProfile() + GuiProfile()
+ Check("root.[children].0.[values].0.value", "\"item 0\"", "@QVariant (@QString)"); + Check("root.[children].0.[values].0.role", "Qt::DisplayRole (0)", "@Qt::ItemDataRole")
+ Check("root.[children].0.[values].0.value", "\"item 0\"", "@QVariant (QString)");
QTest::newRow("Internal1") QTest::newRow("Internal1")

View File

@@ -8,5 +8,5 @@ QtcAutotest {
targetName: testName // Test runner hardcodes the names of the executables targetName: testName // Test runner hardcodes the names of the executables
destinationDirectory: project.buildDirectory + '/' destinationDirectory: project.buildDirectory + '/'
+ qtc.ide_bin_path + '/testapps/' + testName + qtc.ide_bin_path + '/testapps/' + testName
files: "main.cpp" files: sourceDirectory + "/main.cpp"
} }