Merge remote-tracking branch 'origin/4.2'
Conflicts: qbs/modules/qtc/qtc.qbs qtcreator.pri src/shared/qbs Change-Id: I5050baa31f4a892d00cd6f7e088d1b597921474d
|
Before Width: | Height: | Size: 16 KiB After Width: | Height: | Size: 18 KiB |
BIN
doc/images/navigator.png
Normal file
|
After Width: | Height: | Size: 434 B |
|
Before Width: | Height: | Size: 15 KiB After Width: | Height: | Size: 16 KiB |
|
Before Width: | Height: | Size: 35 KiB After Width: | Height: | Size: 36 KiB |
BIN
doc/images/statistics.png
Normal file
|
After Width: | Height: | Size: 258 B |
@@ -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
|
||||||
|
|
||||||
|
|||||||
@@ -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
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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.
|
||||||
|
|
||||||
|
|||||||
@@ -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.
|
||||||
|
|||||||
@@ -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
|
||||||
|
|
||||||
|
|||||||
@@ -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):
|
||||||
|
|||||||
@@ -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,6 +1564,7 @@ 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)
|
||||||
|
|
||||||
|
if result:
|
||||||
self.knownStaticMetaObjects[someTypeName] = 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)
|
||||||
|
|
||||||
|
|||||||
@@ -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.
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
@@ -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):
|
||||||
|
|||||||
@@ -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
|
|
||||||
with Children(d):
|
|
||||||
short = d.putSubItem("data", i.dereference())
|
|
||||||
if d.isMsvcTarget():
|
|
||||||
refcount = value["_Rep"]
|
|
||||||
d.putIntItem("usecount", refcount["_Uses"])
|
|
||||||
d.putIntItem("weakcount", refcount["_Weaks"])
|
|
||||||
else:
|
else:
|
||||||
refcount = value["_M_refcount"]["_M_pi"]
|
d.putItem(i.dereference())
|
||||||
d.putIntItem("usecount", refcount["_M_use_count"])
|
d.putBetterType(value.type)
|
||||||
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"]
|
||||||
|
|||||||
@@ -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, ¶ms)))
|
||||||
|
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);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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>
|
||||||
template<template<typename> class Container, template<typename> class InputContainer, typename IT, typename Function>
|
struct ContainerType
|
||||||
using ResultContainer = Container<decay_t<result_of_t<Function(IT)>>>;
|
|
||||||
|
|
||||||
} // anonymous
|
|
||||||
|
|
||||||
// different container types for input and output, e.g. transforming a QList into a QSet
|
|
||||||
template<template<typename> class C, // result container type
|
|
||||||
template<typename> class SC, // input container type
|
|
||||||
typename T, // input value type
|
|
||||||
typename F> // function type
|
|
||||||
Q_REQUIRED_RESULT
|
|
||||||
auto transform(const SC<T> &container, F function) -> ResultContainer<C, SC, T, F>
|
|
||||||
{
|
{
|
||||||
ResultContainer<C, SC, T, F> result;
|
|
||||||
|
};
|
||||||
|
|
||||||
|
// 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(),
|
std::transform(container.begin(), container.end(),
|
||||||
inserter(result),
|
inserter(result),
|
||||||
function);
|
function);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
// different container types for input and output, e.g. transforming a QList into a QSet
|
template <typename R, typename S>
|
||||||
// for member function pointers
|
|
||||||
template<template<typename> class C, // result container type
|
|
||||||
template<typename> class SC, // input container type
|
|
||||||
typename T, // input value type
|
|
||||||
typename R,
|
|
||||||
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>
|
static C call(const SC &container, R (S::*p)() const)
|
||||||
{
|
{
|
||||||
return Utils::transform<C, SC, T>(container, std::mem_fn(p));
|
return call(container, std::mem_fn(p));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
// same container type for input and output, e.g. transforming a QList<QString> into QList<int>
|
// same container type for input and output, e.g. transforming a QList<QString> into QList<int>
|
||||||
// or QStringList -> QList<>
|
// or QStringList -> QList<>
|
||||||
template<template<typename> class C, // container
|
template<typename C, // container
|
||||||
typename T, // container value type
|
|
||||||
typename F>
|
typename F>
|
||||||
Q_REQUIRED_RESULT
|
Q_REQUIRED_RESULT
|
||||||
auto transform(const C<T> &container, F function) -> ResultContainer<C, C, T, F>
|
auto transform(const C &container, F function)
|
||||||
|
-> typename ContainerType<C>::template ResultOfTransform<F>
|
||||||
{
|
{
|
||||||
return Utils::transform<C, C, T>(container, function);
|
return TransformImpl<
|
||||||
|
typename ContainerType<C>::template ResultOfTransform<F>,
|
||||||
|
C
|
||||||
|
>::call(container, function);
|
||||||
}
|
}
|
||||||
|
|
||||||
// same container type for member function pointer
|
// same container type for member function pointer
|
||||||
template<template<typename> class C, // container
|
template<typename C,
|
||||||
typename T, // container value type
|
|
||||||
typename R,
|
typename R,
|
||||||
typename S>
|
typename S>
|
||||||
Q_REQUIRED_RESULT
|
Q_REQUIRED_RESULT
|
||||||
auto transform(const C<T> &container, R (S::*p)() const) -> ResultContainer<C, C, T, R(S::*)() const>
|
auto transform(const C &container, R (S::*p)() const)
|
||||||
|
->typename ContainerType<C>::template ResultOfTransformPMF<R>
|
||||||
{
|
{
|
||||||
return Utils::transform<C, C, T>(container, std::mem_fn(p));
|
return TransformImpl<
|
||||||
|
typename ContainerType<C>::template ResultOfTransformPMF<R>,
|
||||||
|
C
|
||||||
|
>::call(container, p);
|
||||||
}
|
}
|
||||||
|
|
||||||
// QStringList different containers
|
// 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
|
||||||
typename F>
|
typename SC, // input container type
|
||||||
|
typename F> // function type
|
||||||
Q_REQUIRED_RESULT
|
Q_REQUIRED_RESULT
|
||||||
auto transform(const QStringList &container, F function) -> ResultContainer<C, QList, QString, F>
|
auto transform(const SC &container, F function)
|
||||||
|
-> typename ContainerType<SC>::template ResultOfTransform<F, C>
|
||||||
{
|
{
|
||||||
return Utils::transform<C, QList, QString>(container, function);
|
return TransformImpl<
|
||||||
|
typename ContainerType<SC>::template ResultOfTransform<F, C>,
|
||||||
|
SC
|
||||||
|
>::call(container, function);
|
||||||
}
|
}
|
||||||
|
|
||||||
// QStringList -> QList
|
// different container types for input and output, e.g. transforming a QList into a QSet
|
||||||
template<typename F>
|
// for member function pointers
|
||||||
|
template<template<typename> class C, // result container type
|
||||||
|
typename SC, // input container type
|
||||||
|
typename R,
|
||||||
|
typename S>
|
||||||
Q_REQUIRED_RESULT
|
Q_REQUIRED_RESULT
|
||||||
auto transform(const QStringList &container, F function) -> ResultContainer<QList, QList, QString, F>
|
auto transform(const SC &container, R (S::*p)() const)
|
||||||
|
-> C<decay_t<R>>
|
||||||
{
|
{
|
||||||
return Utils::transform<QList, QList, QString>(container, function);
|
return TransformImpl<
|
||||||
|
C<decay_t<R>>,
|
||||||
|
SC
|
||||||
|
>::call(container, p);
|
||||||
}
|
}
|
||||||
|
|
||||||
//////////////////
|
//////////////////
|
||||||
|
|||||||
@@ -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();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -62,6 +62,11 @@ AutotoolsBuildConfiguration::AutotoolsBuildConfiguration(Target *parent) :
|
|||||||
// /<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();
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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) {
|
||||||
|
|||||||
@@ -102,6 +102,7 @@ void Find::destroy()
|
|||||||
{
|
{
|
||||||
delete m_instance;
|
delete m_instance;
|
||||||
m_instance = 0;
|
m_instance = 0;
|
||||||
|
if (d) {
|
||||||
delete d->m_currentDocumentFind;
|
delete d->m_currentDocumentFind;
|
||||||
delete d->m_findToolBar;
|
delete d->m_findToolBar;
|
||||||
delete d->m_findDialog;
|
delete d->m_findDialog;
|
||||||
@@ -109,6 +110,7 @@ void Find::destroy()
|
|||||||
delete d->m_searchResultWindow;
|
delete d->m_searchResultWindow;
|
||||||
delete d;
|
delete d;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Find *Find::instance()
|
Find *Find::instance()
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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))
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|
||||||
|
|||||||
@@ -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();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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();
|
||||||
|
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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();
|
||||||
|
|||||||
@@ -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();
|
||||||
|
|||||||
@@ -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")
|
||||||
|
|||||||
@@ -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"
|
||||||
}
|
}
|
||||||
|
|||||||