diff --git a/doc/images/creator-qbs-build-app.png b/doc/images/creator-qbs-build-app.png index 29e45f84fba..43228c25617 100644 Binary files a/doc/images/creator-qbs-build-app.png and b/doc/images/creator-qbs-build-app.png differ diff --git a/doc/images/navigator.png b/doc/images/navigator.png new file mode 100644 index 00000000000..69d9a6e491e Binary files /dev/null and b/doc/images/navigator.png differ diff --git a/doc/images/qtcreator-clang-code-model-options.png b/doc/images/qtcreator-clang-code-model-options.png index cd28c697d9c..ff9e367c022 100644 Binary files a/doc/images/qtcreator-clang-code-model-options.png and b/doc/images/qtcreator-clang-code-model-options.png differ diff --git a/doc/images/qtcreator-scxml-editor.png b/doc/images/qtcreator-scxml-editor.png index 2598cfead8d..c9512046ddf 100644 Binary files a/doc/images/qtcreator-scxml-editor.png and b/doc/images/qtcreator-scxml-editor.png differ diff --git a/doc/images/statistics.png b/doc/images/statistics.png new file mode 100644 index 00000000000..b9fa730a49a Binary files /dev/null and b/doc/images/statistics.png differ diff --git a/doc/src/debugger/creator-debugger-setup.qdoc b/doc/src/debugger/creator-debugger-setup.qdoc index 8887ea5ceb7..0e5d9c0261a 100644 --- a/doc/src/debugger/creator-debugger-setup.qdoc +++ b/doc/src/debugger/creator-debugger-setup.qdoc @@ -236,7 +236,7 @@ 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 - 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 diff --git a/doc/src/editors/creator-clang-codemodel.qdoc b/doc/src/editors/creator-clang-codemodel.qdoc index 5073cdaaf0d..6d8fbb1d92c 100644 --- a/doc/src/editors/creator-clang-codemodel.qdoc +++ b/doc/src/editors/creator-clang-codemodel.qdoc @@ -160,9 +160,15 @@ {Options to Request or Suppress Warnings} or the GCC or Clang 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. + \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 */ diff --git a/doc/src/editors/creator-diff-editor.qdoc b/doc/src/editors/creator-diff-editor.qdoc index 391a6171183..78c1c0274e1 100644 --- a/doc/src/editors/creator-diff-editor.qdoc +++ b/doc/src/editors/creator-diff-editor.qdoc @@ -83,8 +83,7 @@ To only show text changes, select \uicontrol {Ignore Whitespace}. 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 - file. + show in \uicontrol {Context lines}. By default, the horizontal scroll bars in the left and right pane are synchronized. To use them independently of each other, select the diff --git a/doc/src/editors/creator-modeling.qdoc b/doc/src/editors/creator-modeling.qdoc index 3b7acd31f83..2c09149a123 100644 --- a/doc/src/editors/creator-modeling.qdoc +++ b/doc/src/editors/creator-modeling.qdoc @@ -91,10 +91,13 @@ To keep the selections in the diagram and the \uicontrol Structure view synchronized, select \uicontrol {Keep Synchronized}. - To zoom into diagrams, press \key Ctrl++ or press \key Ctrl and roll the - mouse wheel up. To zoom out of diagrams, press \key Ctrl+- or press - \key Ctrl and roll the mouse wheel down. To reset the diagram size to 100%, - select \key Ctrl+0. + To zoom into diagrams, select \uicontrol Tools > \uicontrol {Model Editor} > + \uicontrol {Zoom In}, press \key Ctrl++, or press \key Ctrl and roll the + mouse wheel up. To zoom out of diagrams, select \uicontrol Tools > + \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 the editor to copy all elements to the clipboard by using 300 dpi. Then diff --git a/doc/src/projects/creator-projects-qbs.qdoc b/doc/src/projects/creator-projects-qbs.qdoc index b67f9f2bf43..71cb8da33d4 100644 --- a/doc/src/projects/creator-projects-qbs.qdoc +++ b/doc/src/projects/creator-projects-qbs.qdoc @@ -128,6 +128,9 @@ \li Select \uicontrol {Show command lines} to print actual command lines 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 after building them. This option is enabled by default. diff --git a/doc/src/projects/creator-projects-settings-overview.qdoc b/doc/src/projects/creator-projects-settings-overview.qdoc index e31cac5f055..f8a0e38c4eb 100644 --- a/doc/src/projects/creator-projects-settings-overview.qdoc +++ b/doc/src/projects/creator-projects-settings-overview.qdoc @@ -41,23 +41,29 @@ build and run settings for the development targets might be set up automatically in \QC. - To view and modify the settings for currently open projects, switch to the - \uicontrol Projects mode by pressing \key Ctrl+5. + When you open a project for the first time, the + \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 - open projects and use the \uicontrol Build menu commands to build, deploy, and - run projects. + To maintain the list of active kits for a currently open project, switch to + the \uicontrol Projects mode by pressing \key Ctrl+5. - \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 - To enable kits for the project, click them in \uicontrol {Build & Run}. The - list displays kits that are configured in \uicontrol Tools > + The list displays kits that are configured in \uicontrol Tools > \uicontrol Options > \uicontrol {Build & Run} > \uicontrol Kits. To modify - kit configuration or to add kits to the list, select - \uicontrol {Manage Kits} in the context menu. For more information about - managing kits, see \l{Adding Kits}. + kit configuration or to add kits to the list, right-click the sidebar to + open a context-menu, and then select \uicontrol {Manage Kits}. For more + information about managing kits, see \l{Adding Kits}. Each kit consists of a set of values that define one environment, such as a 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 \uicontrol {Copy Steps from Other Kit} in the context menu. - To disable a kit for the project, select \uicontrol {Disable Kit for Project} - in the context menu. + To deactivate a kit, select \uicontrol {Disable Kit for Project} in the + 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 \uicontrol {Import Existing Build} in the context menu. \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 - - \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: + In addition, you can modify the following global settings for each project: \list @@ -102,14 +97,14 @@ \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{To-Do Entries}{To-Do} (experimental) \endlist - \endlist If you have multiple projects open in \QC, select the project to configure in the list of projects. diff --git a/doc/src/qtquick/qtquick-screens.qdoc b/doc/src/qtquick/qtquick-screens.qdoc index 5aa994c3a13..5758756151c 100644 --- a/doc/src/qtquick/qtquick-screens.qdoc +++ b/doc/src/qtquick/qtquick-screens.qdoc @@ -114,7 +114,7 @@ \li \l{Using Layouts} - \li \l{Using Split Views} + \li \l{Organizing Items} \endlist @@ -269,12 +269,29 @@ \uicontrol Layout > \uicontrol {Fill Width} in the context menu. To make the item as 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 - horizontally or vertically - with a draggable splitter between each item. + From Qt 5.7, you can use the following \l{Qt Quick Controls 2} types to + organize items on screens: + \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 @@ -382,62 +399,68 @@ \endlist - From Qt 5.1, you can also use the following - \l{Qt Quick Controls} to present or receive input from the user: + Since Qt 5.7, you can also use the following \l{Qt Quick Controls 2} types + to inform users about the progress of the application or to gather input + from the user: \list - \li \l{Button} provides a push button that you can associate with an - action. + \li \l [QtQuickControls2]{BusyIndicator}{Busy Indicator} indicates + activity while content is being loaded. - \li CheckBox provides an option button that can be toggled on - (checked) or off (unchecked). + \li \l [QtQuickControls2]{Button} provides a push button that you can + associate with an action. - \li ComboBox provides a drop-down list. Add items to the combo box by - assigning it a ListModel, or a list of strings to the model - property. + \li \l [QtQuickControls2]{CheckBox}{Check Box} provides an option button + that can be toggled on (checked) or off (unchecked). - \li GroupBox provides a frame, a title on top, and place for various - other controls inside the frame. + \li \l [QtQuickControls2]{CheckDelegate}{Check Delegate} presents an + 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 - of the system. + \li \l [QtQuickControls2]{ComboBox}{Combo Box} is a combined button and + 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 - (checked) or off (unchecked). + \li \l [QtQuickControls2]{ItemDelegate}{Item Delegate} is a standard + view item that can be used in various views and controls. - \li \l{Slider} - {Slider (Horizontal) and Slider (Vertical)} enable the user to move - a slider handle along a horizontal or vertical groove and translate - the handle's position into a value within the specified range. + \li \l [QtQuickControls2]{ProgressBar}{Progress Bar} indicates the + progress of an operation. - \li SpinBox 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. + \li \l [QtQuickControls2]{RadioButton}{Radio Button} provides an option + button that can be switched on (checked) or off (unchecked). - \omit - Not visible in the item library in 3.2. - \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 \l [QtQuickControls2]{RadioDelegate}{Radio Delegate} presents an + item delegate that can be toggled on (checked) or off (unchecked). - \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 - Not visible in the item library in 3.2. - \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 \l [QtQuickControls2]{Switch} is an option button that can be + toggled on or off. - \li ToolButton provides a button that is functionally similar to - \uicontrol Button, but that looks more suitable on a \uicontrol {Tool Bar}. + \li \l [QtQuickControls2]{TextArea}{Text Area} displays multiple lines + 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 diff --git a/share/qtcreator/debugger/boosttypes.py b/share/qtcreator/debugger/boosttypes.py index 552b0594120..17d553da84c 100644 --- a/share/qtcreator/debugger/boosttypes.py +++ b/share/qtcreator/debugger/boosttypes.py @@ -65,12 +65,8 @@ def qdump__boost__shared_ptr(d, value): d.check(weakcount >= 0) d.check(weakcount <= usecount) d.check(usecount <= 10*1000*1000) - - with Children(d): - short = d.putSubItem("data", d.createValue(px, value.type[0])) - d.putIntItem("weakcount", weakcount) - d.putIntItem("usecount", usecount) - d.putValue(short.value, short.encoding) + d.putItem(d.createValue(px, value.type[0])) + d.putBetterType(value.type) def qdump__boost__container__list(d, value): diff --git a/share/qtcreator/debugger/dumper.py b/share/qtcreator/debugger/dumper.py index 104c20a5f4d..cfeb8f652a8 100644 --- a/share/qtcreator/debugger/dumper.py +++ b/share/qtcreator/debugger/dumper.py @@ -253,6 +253,9 @@ class DumperBase: self.typesReported = {} self.typesToReport = {} self.qtNamespaceToReport = None + self.qtCustomEventFunc = 0 + self.qtCustomEventPltFunc = 0 + self.qtPropertyFunc = 0 self.passExceptions = False self.isTesting = False @@ -303,7 +306,7 @@ class DumperBase: self.forceQtNamespace = int(args.get('forcens', '0')) self.passExceptions = int(args.get('passexceptions', '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.autoDerefPointers = int(args.get('autoderef', '0')) self.partialVariable = args.get('partialvar', '') @@ -790,6 +793,13 @@ class DumperBase: self.putField('keyencoded', key.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): with SubItem(self, name): try: @@ -1366,11 +1376,13 @@ class DumperBase: def putQObjectNameValue(self, value): try: - intSize = 4 - ptrSize = self.ptrSize() # dd = value['d_ptr']['d'] is just behind the vtable. (vtable, dd) = self.split('pp', value) + if not self.couldBeQObjectVTable(vtable): + return False + intSize = 4 + ptrSize = self.ptrSize() if self.qtVersion() < 0x050000: # Size of QObjectData: 5 pointer + 2 int # - vtable @@ -1421,97 +1433,62 @@ class DumperBase: except: # warn('NO QOBJECT: %s' % value.type) - pass + return False - def canBePointer(self, p): + def couldBePointer(self, p): if self.ptrSize() == 4: return p > 100000 and (p & 0x3 == 0) else: return p > 100000 and (p & 0x7 == 0) and (p < 0x7fffffffffff) - def canBeVTableEntry(self, p): + def couldBeVTableEntry(self, p): if self.ptrSize() == 4: return p > 100000 and (p & 0x1 == 0) else: return p > 100000 and (p & 0x1 == 0) and (p < 0x7fffffffffff) - def couldBeQObject(self, objectPtr): + def couldBeQObjectPointer(self, objectPtr): try: - (vtablePtr, dd) = self.split('pp', objectPtr) + vtablePtr, dd = self.split('pp', objectPtr) except: self.bump('nostruct-1') 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: - metaObjectFunc, metaCastFunc, metaCallFunc = self.split('ppp', vtablePtr) - 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(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) + dvtablePtr, qptr, parentPtr = self.split('ppp', dd) except: self.bump('nostruct-2') 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 if qptr != objectPtr: - #warn('QPTR: 0x%x 0x%x' % (qptr, objectPtr)) self.bump('q_ptr') 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 True + return self.couldBeQObjectVTable(vtablePtr) + 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): """ objectPtr - address of *potential* instance of QObject derived class @@ -1521,7 +1498,7 @@ class DumperBase: self.checkIntType(objectPtr) def extractMetaObjectPtrFromAddress(): - return 0 + #return 0 # FIXME: Calling 'works' but seems to impact memory contents(!) # in relevant places. One symptom is that object name # contents 'vanishes' as the reported size of the string @@ -1535,7 +1512,7 @@ class DumperBase: res = self.parseAndEvaluate(cmd) #warn('MO RES: %s' % res) self.bump('successfulMetaObjectCall') - return toInteger(res) + return res.pointer() except: self.bump('failedMetaObjectCall') #warn('COULD NOT EXECUTE: %s' % cmd) @@ -1587,7 +1564,8 @@ class DumperBase: # if base is not None and base != someTypeObj: # sanity check # result = extractStaticMetaObjectPtrFromType(base) - self.knownStaticMetaObjects[someTypeName] = result + if result: + self.knownStaticMetaObjects[someTypeName] = result return result @@ -1603,7 +1581,7 @@ class DumperBase: #warn('CACHED RESULT: %s %s 0x%x' % (self.currentIName, typeName, result)) return result - if not self.couldBeQObject(objectPtr): + if not self.couldBeQObjectPointer(objectPtr): self.bump('cannotBeQObject') #warn('DOES NOT LOOK LIKE A QOBJECT: %s' % self.currentIName) return 0 @@ -1683,8 +1661,11 @@ class DumperBase: self.putNumChild(0) # This is called is when a QObject derived class is expanded - def putQObjectGuts(self, qobject, metaObjectPtr): - self.putQObjectGutsHelper(qobject, qobject.address(), -1, metaObjectPtr, 'QObject') + def tryPutQObjectGuts(self, value): + metaObjectPtr = self.extractMetaObjectPtr(value.address(), value.type) + if metaObjectPtr: + self.putQObjectGutsHelper(value, value.address(), + -1, metaObjectPtr, 'QObject') def metaString(self, metaObjectPtr, index, revision): ptrSize = self.ptrSize() @@ -1787,7 +1768,7 @@ class DumperBase: qobjectPtrType = self.createType('QObject') # FIXME. with SubItem(self, '[parent]'): self.putField('sortgroup', 9) - self.putItem(self.createValue(dd + 2 * ptrSize, qobjectPtrType)) + self.putItem(self.createValue(parentPtr, qobjectPtrType)) with SubItem(self, '[children]'): self.putField('sortgroup', 8) base = self.extractPointer(dd + 3 * ptrSize) # It's a QList @@ -1881,8 +1862,21 @@ class DumperBase: if qobject: # LLDB doesn't like calling it on a derived class, possibly # due to type information living in a different shared object. - base = self.createValue(qobjectPtr, '@QObject') - self.putCallItem(name, '@QVariant', base, 'property', '"' + name + '"') + #base = self.createValue(qobjectPtr, '@QObject') + #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: putt(name, ' ') @@ -2679,23 +2673,16 @@ class DumperBase: self.putNumChild(1) self.putEmptyValue() #warn('STRUCT GUTS: %s ADDRESS: 0x%x ' % (value.name, value.address())) - metaObjectPtr = self.extractMetaObjectPtr(value.address(), value.type) if self.showQObjectNames: self.preping(self.currentIName) - metaObjectPtr = self.extractMetaObjectPtr(value.address(), value.type) - self.ping(self.currentIName) - if metaObjectPtr: - self.context = value self.putQObjectNameValue(value) - #warn('STRUCT GUTS: %s MO: 0x%x ' % (self.currentIName, metaObjectPtr)) + self.ping(self.currentIName) if self.isExpanded(): self.putField('sortable', 1) with Children(self, 1, childType=None): self.putFields(value) - if not self.showQObjectNames: - metaObjectPtr = self.extractMetaObjectPtr(value.address(), value.type) - if metaObjectPtr: - self.putQObjectGuts(value, metaObjectPtr) + if self.showQObjectNames: + self.tryPutQObjectGuts(value) def symbolAddress(self, symbolName): res = self.parseAndEvaluate('(size_t)&' + symbolName) @@ -3275,7 +3262,7 @@ class DumperBase: except: return None #warn('VTBL: 0x%x' % vtbl) - if not self.dumper.canBePointer(vtbl): + if not self.dumper.couldBePointer(vtbl): return None return self.dumper.nativeDynamicTypeName(address, self) diff --git a/share/qtcreator/debugger/gdbbridge.py b/share/qtcreator/debugger/gdbbridge.py index f78b5fc6f42..ae3336569d5 100644 --- a/share/qtcreator/debugger/gdbbridge.py +++ b/share/qtcreator/debugger/gdbbridge.py @@ -1010,6 +1010,12 @@ class Dumper(DumperBase): self.ping('qtNamespace') return res + def findSymbol(self, symbolName): + try: + return toInteger(gdb.parse_and_eval("(size_t)&'%s'" % symbolName)) + except: + return 0 + def qtNamespaceX(self): if not self.currentQtNamespaceGuess is None: return self.currentQtNamespaceGuess @@ -1039,6 +1045,24 @@ class Dumper(DumperBase): except: 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 # a libQt5Core and could not extract a namespace. # The best guess is that there isn't any. diff --git a/share/qtcreator/debugger/lldbbridge.py b/share/qtcreator/debugger/lldbbridge.py index b54a34b4f4e..bf3dae2f2db 100644 --- a/share/qtcreator/debugger/lldbbridge.py +++ b/share/qtcreator/debugger/lldbbridge.py @@ -679,6 +679,15 @@ class Dumper(DumperBase): qtVersion = 0x10000 * int(major) + 0x100 * int(minor) + int(patch) 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 ('', 0x50200) diff --git a/share/qtcreator/debugger/qttypes.py b/share/qtcreator/debugger/qttypes.py index b964e8b7810..8e32a19c811 100644 --- a/share/qtcreator/debugger/qttypes.py +++ b/share/qtcreator/debugger/qttypes.py @@ -190,6 +190,34 @@ def qdump_X_QModelIndex(d, value): d.putCallItem('parent', '@QModelIndex', value, 'parent') #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): role, pad, val = value.split('{@Qt::ItemDataRole}@{QVariant}') d.putPairContents(role.value(), (role, val), 'role', 'value') @@ -202,8 +230,9 @@ def qdump__QStandardItem(d, value): if d.isExpanded(): with Children(d): d.putSubItem('[model]', d.createValue(model, '@QStandardItemModel')) - d.putSubItem('[values]', d.createVectorItem(values, 'QStandardItemData')) - d.putSubItem('[children]', d.createVectorItem(children, '@QStandardItem*')) + d.putSubItem('[values]', d.createVectorItem(values, '@QStandardItemData')) + d.putSubItem('[children]', d.createVectorItem(children, + d.createPointerType(value.type))) def qdump__QDate(d, value): diff --git a/share/qtcreator/debugger/stdtypes.py b/share/qtcreator/debugger/stdtypes.py index c4d050a6173..6dc82a7c95e 100644 --- a/share/qtcreator/debugger/stdtypes.py +++ b/share/qtcreator/debugger/stdtypes.py @@ -657,6 +657,9 @@ def qdump__std____weak_ptr(d, value): def qdump__std__weak_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): if d.isMsvcTarget(): @@ -667,41 +670,27 @@ def qdump__std__shared_ptr(d, value): if i.pointer() == 0: d.putValue("(null)") 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: - 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) + else: + d.putItem(i.dereference()) + d.putBetterType(value.type) def qdump__std____1__shared_ptr(d, value): i = value["__ptr_"] if i.pointer() == 0: d.putValue("(null)") d.putNumChild(0) - return - with Children(d): - short = d.putSubItem("data", i.dereference()) - 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) + else: + d.putItem(i.dereference()) + d.putBetterType(value.type) def qdump__std__unique_ptr(d, value): p = d.extractPointer(value) if p == 0: d.putValue("(null)") d.putNumChild(0) - return - with Children(d): - short = d.putSubItem("data", d.createValue(p, value.type[0])) - d.putValue(short.value, short.encoding) + else: + d.putItem(d.createValue(p, value.type[0])) + d.putBetterType(value.type) def qdump__std____1__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): 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): ht = value["_M_ht"] diff --git a/src/libs/qtcreatorcdbext/pyvalue.cpp b/src/libs/qtcreatorcdbext/pyvalue.cpp index 6e5fb53d3ec..a39d8eb7e76 100644 --- a/src/libs/qtcreatorcdbext/pyvalue.cpp +++ b/src/libs/qtcreatorcdbext/pyvalue.cpp @@ -32,9 +32,14 @@ #include "stringutils.h" #include "symbolgroupvalue.h" +#include +#include + constexpr bool debugPyValue = false; constexpr bool debuggingValueEnabled() { return debugPyValue || debugPyCdbextModule; } +static std::map> valuesForSymbolGroup; + std::string getSymbolName(CIDebugSymbolGroup *sg, ULONG index) { ULONG size = 0; @@ -147,6 +152,21 @@ PyObject *value_Address(Value *self) 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) { DEBUG_SYMBOL_PARAMETERS params; @@ -154,7 +174,15 @@ bool expandValue(Value *v) return false; if (params.Flags & DEBUG_SYMBOL_EXPANDED) 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) @@ -310,8 +338,11 @@ PyObject *value_ChildFromIndex(Value *self, PyObject *args) 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 *) { @@ -339,6 +370,7 @@ PyObject *createValue(ULONG index, CIDebugSymbolGroup *symbolGroup) if (value != NULL) { value->m_index = index; value->m_symbolGroup = symbolGroup; + valuesForSymbolGroup[symbolGroup].push_back(value); } return reinterpret_cast(value); } diff --git a/src/libs/utils/algorithm.h b/src/libs/utils/algorithm.h index 10b6daef94f..76645e3311a 100644 --- a/src/libs/utils/algorithm.h +++ b/src/libs/utils/algorithm.h @@ -214,78 +214,112 @@ using decay_t = typename std::decay::type; template using result_of_t = typename std::result_of::type; -// Result type of transform operation +// abstraction to treat Container and QStringList similarly +template +struct ContainerType +{ -template class Container, template class InputContainer, typename IT, typename Function> -using ResultContainer = Container>>; +}; -} // anonymous +// specialization for qt container T_Container +template class T_Container, typename T_Type> +struct ContainerType> +{ + template class C = T_Container> + using ResultOfTransform = C>>; + + template + using ResultOfTransformPMF = T_Container>; +}; + +// specialization for QStringList +template<> +struct ContainerType : ContainerType> +{ +}; + +} + +// actual implementation of transform +template // input container type +struct TransformImpl { + template + 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 + 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 into QList +// or QStringList -> QList<> +template +Q_REQUIRED_RESULT +auto transform(const C &container, F function) +-> typename ContainerType::template ResultOfTransform +{ + return TransformImpl< + typename ContainerType::template ResultOfTransform, + C + >::call(container, function); +} + +// same container type for member function pointer +template +Q_REQUIRED_RESULT +auto transform(const C &container, R (S::*p)() const) + ->typename ContainerType::template ResultOfTransformPMF +{ + return TransformImpl< + typename ContainerType::template ResultOfTransformPMF, + C + >::call(container, p); +} // different container types for input and output, e.g. transforming a QList into a QSet template class C, // result container type - template class SC, // input container type - typename T, // input value type + typename SC, // input container type typename F> // function type Q_REQUIRED_RESULT -auto transform(const SC &container, F function) -> ResultContainer +auto transform(const SC &container, F function) + -> typename ContainerType::template ResultOfTransform { - ResultContainer result; - std::transform(container.begin(), container.end(), - inserter(result), - function); - return result; + return TransformImpl< + typename ContainerType::template ResultOfTransform, + SC + >::call(container, function); } // different container types for input and output, e.g. transforming a QList into a QSet // for member function pointers template class C, // result container type - template class SC, // input container type - typename T, // input value type + typename SC, // input container type typename R, typename S> Q_REQUIRED_RESULT -auto transform(const SC &container, R (S::*p)() const) -> ResultContainer +auto transform(const SC &container, R (S::*p)() const) + -> C> { - return Utils::transform(container, std::mem_fn(p)); -} - -// same container type for input and output, e.g. transforming a QList into QList -// or QStringList -> QList<> -template class C, // container - typename T, // container value type - typename F> -Q_REQUIRED_RESULT -auto transform(const C &container, F function) -> ResultContainer -{ - return Utils::transform(container, function); -} - -// same container type for member function pointer -template class C, // container - typename T, // container value type - typename R, - typename S> -Q_REQUIRED_RESULT -auto transform(const C &container, R (S::*p)() const) -> ResultContainer -{ - return Utils::transform(container, std::mem_fn(p)); -} - -// QStringList different containers -template class C, // result container type - typename F> -Q_REQUIRED_RESULT -auto transform(const QStringList &container, F function) -> ResultContainer -{ - return Utils::transform(container, function); -} - -// QStringList -> QList -template -Q_REQUIRED_RESULT -auto transform(const QStringList &container, F function) -> ResultContainer -{ - return Utils::transform(container, function); + return TransformImpl< + C>, + SC + >::call(container, p); } ////////////////// diff --git a/src/plugins/autotest/testcodeparser.cpp b/src/plugins/autotest/testcodeparser.cpp index fe4c1132f1e..dab7f80f672 100644 --- a/src/plugins/autotest/testcodeparser.cpp +++ b/src/plugins/autotest/testcodeparser.cpp @@ -155,8 +155,6 @@ void TestCodeParser::updateTestTree() return; m_fullUpdatePostponed = false; - - emit aboutToPerformFullParse(); qCDebug(LOG) << "calling scanForTests (updateTestTree)"; scanForTests(); } @@ -199,6 +197,7 @@ void TestCodeParser::onStartupProjectChanged(ProjectExplorer::Project *project) qCDebug(LOG) << "Canceling scanForTest (startup project changed)"; Core::ProgressManager::instance()->cancelTasks(Constants::TASK_PARSE); } + emit aboutToPerformFullParse(); if (project) emitUpdateTestTree(); } diff --git a/src/plugins/autotoolsprojectmanager/autotoolsbuildconfiguration.cpp b/src/plugins/autotoolsprojectmanager/autotoolsbuildconfiguration.cpp index b3fca076658..5095c0e57a7 100644 --- a/src/plugins/autotoolsprojectmanager/autotoolsbuildconfiguration.cpp +++ b/src/plugins/autotoolsprojectmanager/autotoolsbuildconfiguration.cpp @@ -59,9 +59,14 @@ using namespace ProjectExplorer::Constants; AutotoolsBuildConfiguration::AutotoolsBuildConfiguration(Target *parent) : BuildConfiguration(parent, Core::Id(AUTOTOOLS_BC_ID)) { - // / is used so the un-changed check in setBuildDirectory() works correctly. - // The leading / is to avoid the relative the path expansion in BuildConfiguration::buildDirectory. - BuildConfiguration::setBuildDirectory(Utils::FileName::fromString(QString::fromLatin1("/"))); + // / is used so the un-changed check in setBuildDirectory() works correctly. + // The leading / is to avoid the relative the path expansion in BuildConfiguration::buildDirectory. + BuildConfiguration::setBuildDirectory(Utils::FileName::fromString(QString::fromLatin1("/"))); + + connect(this, &BuildConfiguration::buildDirectoryChanged, this, [this] { + foreach (auto bs, stepList(BUILDSTEPS_BUILD)->allOfType()) + bs->notifyBuildDirectoryChanged(); + }); } NamedWidget *AutotoolsBuildConfiguration::createConfigWidget() @@ -222,12 +227,3 @@ BuildConfiguration::BuildType AutotoolsBuildConfiguration::buildType() const // TODO: Should I return something different from Unknown? return Unknown; } - -void AutotoolsBuildConfiguration::setBuildDirectory(const Utils::FileName &directory) -{ - if (directory == buildDirectory()) - return; - BuildConfiguration::setBuildDirectory(directory); - foreach (auto bs, stepList(BUILDSTEPS_BUILD)->allOfType()) - bs->notifyBuildDirectoryChanged(); -} diff --git a/src/plugins/autotoolsprojectmanager/autotoolsbuildconfiguration.h b/src/plugins/autotoolsprojectmanager/autotoolsbuildconfiguration.h index 3bceb4cc3aa..3d7f170f5b4 100644 --- a/src/plugins/autotoolsprojectmanager/autotoolsbuildconfiguration.h +++ b/src/plugins/autotoolsprojectmanager/autotoolsbuildconfiguration.h @@ -36,7 +36,6 @@ namespace Internal { class AutotoolsTarget; class AutotoolsBuildConfigurationFactory; -class AutotoolsBuildSettingsWidget; class AutotoolsBuildConfiguration : public ProjectExplorer::BuildConfiguration { @@ -53,11 +52,6 @@ public: protected: AutotoolsBuildConfiguration(ProjectExplorer::Target *parent, Core::Id id); AutotoolsBuildConfiguration(ProjectExplorer::Target *parent, AutotoolsBuildConfiguration *source); - - friend class AutotoolsBuildSettingsWidget; - -private: - void setBuildDirectory(const Utils::FileName &directory) override; }; class AutotoolsBuildConfigurationFactory : public ProjectExplorer::IBuildConfigurationFactory diff --git a/src/plugins/cmakeprojectmanager/cmakekitinformation.cpp b/src/plugins/cmakeprojectmanager/cmakekitinformation.cpp index f7606c41bc1..18c7a672ebb 100644 --- a/src/plugins/cmakeprojectmanager/cmakekitinformation.cpp +++ b/src/plugins/cmakeprojectmanager/cmakekitinformation.cpp @@ -411,8 +411,8 @@ void CMakeGeneratorKitInformation::fix(Kit *k) void CMakeGeneratorKitInformation::upgrade(Kit *k) { const QVariant value = k->value(GENERATOR_ID); - GeneratorInfo info; if (value.type() != QVariant::Map) { + GeneratorInfo info; const QString fullName = value.toString(); const int pos = fullName.indexOf(" - "); if (pos >= 0) { diff --git a/src/plugins/coreplugin/find/findplugin.cpp b/src/plugins/coreplugin/find/findplugin.cpp index d0d98d3d7cb..9e8d3207bec 100644 --- a/src/plugins/coreplugin/find/findplugin.cpp +++ b/src/plugins/coreplugin/find/findplugin.cpp @@ -102,12 +102,14 @@ void Find::destroy() { delete m_instance; m_instance = 0; - delete d->m_currentDocumentFind; - delete d->m_findToolBar; - delete d->m_findDialog; - ExtensionSystem::PluginManager::removeObject(d->m_searchResultWindow); - delete d->m_searchResultWindow; - delete d; + if (d) { + delete d->m_currentDocumentFind; + delete d->m_findToolBar; + delete d->m_findDialog; + ExtensionSystem::PluginManager::removeObject(d->m_searchResultWindow); + delete d->m_searchResultWindow; + delete d; + } } Find *Find::instance() diff --git a/src/plugins/debugger/debuggeractions.cpp b/src/plugins/debugger/debuggeractions.cpp index 5c225aed955..4e4b28bd618 100644 --- a/src/plugins/debugger/debuggeractions.cpp +++ b/src/plugins/debugger/debuggeractions.cpp @@ -257,15 +257,15 @@ DebuggerSettings::DebuggerSettings() insertItem(ShowQtNamespace, item); item = new SavedAction(this); - item->setSettingsKey(debugModeGroup, QLatin1String("ShowQObjectNames")); + item->setSettingsKey(debugModeGroup, QLatin1String("ShowQObjectNames2")); item->setText(tr("Show QObject names if available")); item->setDialogText(tr("Show QObject names if available")); item->setToolTip(tr("

Displays the objectName property of QObject based items. " "Note that this can negatively impact debugger performance " "even if no QObjects are present.")); item->setCheckable(true); - item->setDefaultValue(false); - item->setValue(false); + item->setDefaultValue(true); + item->setValue(true); insertItem(ShowQObjectNames, item); item = new SavedAction(this); diff --git a/src/plugins/nim/project/nimbuildconfiguration.cpp b/src/plugins/nim/project/nimbuildconfiguration.cpp index d382ec5adb4..81f34e12fb2 100644 --- a/src/plugins/nim/project/nimbuildconfiguration.cpp +++ b/src/plugins/nim/project/nimbuildconfiguration.cpp @@ -54,13 +54,6 @@ BuildConfiguration::BuildType NimBuildConfiguration::buildType() const return BuildConfiguration::Unknown; } -void NimBuildConfiguration::setBuildDirectory(const FileName &dir) -{ - if (dir == buildDirectory()) - return; - BuildConfiguration::setBuildDirectory(dir); -} - bool NimBuildConfiguration::fromMap(const QVariantMap &map) { if (!BuildConfiguration::fromMap(map)) diff --git a/src/plugins/nim/project/nimbuildconfiguration.h b/src/plugins/nim/project/nimbuildconfiguration.h index a205ae1b18e..1228be06806 100644 --- a/src/plugins/nim/project/nimbuildconfiguration.h +++ b/src/plugins/nim/project/nimbuildconfiguration.h @@ -46,8 +46,6 @@ public: ProjectExplorer::BuildConfiguration::BuildType buildType() const override; - void setBuildDirectory(const Utils::FileName &dir) override; - bool fromMap(const QVariantMap &map) override; QVariantMap toMap() const override; diff --git a/src/plugins/projectexplorer/buildconfiguration.cpp b/src/plugins/projectexplorer/buildconfiguration.cpp index 3625990b31a..ec3cf9894f9 100644 --- a/src/plugins/projectexplorer/buildconfiguration.cpp +++ b/src/plugins/projectexplorer/buildconfiguration.cpp @@ -122,6 +122,8 @@ Utils::FileName BuildConfiguration::rawBuildDirectory() const void BuildConfiguration::setBuildDirectory(const Utils::FileName &dir) { + if (dir == m_buildDirectory) + return; m_buildDirectory = dir; emitBuildDirectoryChanged(); } diff --git a/src/plugins/projectexplorer/buildconfiguration.h b/src/plugins/projectexplorer/buildconfiguration.h index dd727abea74..03d42d4dbdc 100644 --- a/src/plugins/projectexplorer/buildconfiguration.h +++ b/src/plugins/projectexplorer/buildconfiguration.h @@ -50,6 +50,7 @@ public: Utils::FileName buildDirectory() const; Utils::FileName rawBuildDirectory() const; + void setBuildDirectory(const Utils::FileName &dir); virtual NamedWidget *createConfigWidget() = 0; virtual QList createSubConfigWidgets(); @@ -96,7 +97,6 @@ protected: BuildConfiguration(Target *target, Core::Id id); BuildConfiguration(Target *target, BuildConfiguration *source); - virtual void setBuildDirectory(const Utils::FileName &dir); void cloneSteps(BuildConfiguration *source); void emitEnvironmentChanged(); diff --git a/src/plugins/projectexplorer/projectexplorer.cpp b/src/plugins/projectexplorer/projectexplorer.cpp index 4e53fc10875..e5fd014e8d5 100644 --- a/src/plugins/projectexplorer/projectexplorer.cpp +++ b/src/plugins/projectexplorer/projectexplorer.cpp @@ -333,11 +333,11 @@ public: QAction *m_projectSelectorActionQuick; QAction *m_runSubProject; - ProjectWindow *m_proWindow; + ProjectWindow *m_proWindow = nullptr; QString m_sessionToRestoreAtStartup; QStringList m_profileMimeTypes; - AppOutputPane *m_outputPane; + AppOutputPane *m_outputPane = nullptr; QList > m_recentProjects; // pair of filename, displayname static const int m_maxRecentProjects = 25; diff --git a/src/plugins/qmakeprojectmanager/qmakebuildconfiguration.cpp b/src/plugins/qmakeprojectmanager/qmakebuildconfiguration.cpp index 9016dcf6e6a..02f85ee487e 100644 --- a/src/plugins/qmakeprojectmanager/qmakebuildconfiguration.cpp +++ b/src/plugins/qmakeprojectmanager/qmakebuildconfiguration.cpp @@ -102,6 +102,8 @@ enum { debug = 0 }; QmakeBuildConfiguration::QmakeBuildConfiguration(Target *target) : QmakeBuildConfiguration(target, Core::Id(QMAKE_BC_ID)) { + connect(this, &BuildConfiguration::buildDirectoryChanged, + this, &QmakeBuildConfiguration::emitProFileEvaluateNeeded); } QmakeBuildConfiguration::QmakeBuildConfiguration(Target *target, Core::Id id) : @@ -223,14 +225,6 @@ bool QmakeBuildConfiguration::isShadowBuild() const return buildDirectory() != target()->project()->projectDirectory(); } -void QmakeBuildConfiguration::setBuildDirectory(const FileName &directory) -{ - if (directory == buildDirectory()) - return; - BuildConfiguration::setBuildDirectory(directory); - emitProFileEvaluateNeeded(); -} - QString QmakeBuildConfiguration::makefile() const { return static_cast(target()->project())->rootProjectNode()->makefile(); diff --git a/src/plugins/qmakeprojectmanager/qmakebuildconfiguration.h b/src/plugins/qmakeprojectmanager/qmakebuildconfiguration.h index 5a956389e7f..6251cc87ba4 100644 --- a/src/plugins/qmakeprojectmanager/qmakebuildconfiguration.h +++ b/src/plugins/qmakeprojectmanager/qmakebuildconfiguration.h @@ -116,7 +116,6 @@ protected: QmakeBuildConfiguration(ProjectExplorer::Target *target, QmakeBuildConfiguration *source); QmakeBuildConfiguration(ProjectExplorer::Target *target, Core::Id id); bool fromMap(const QVariantMap &map) override; - void setBuildDirectory(const Utils::FileName &directory) override; private: void ctor(); diff --git a/tests/auto/debugger/tst_dumpers.cpp b/tests/auto/debugger/tst_dumpers.cpp index 897c1140aab..48e10ce52d6 100644 --- a/tests/auto/debugger/tst_dumpers.cpp +++ b/tests/auto/debugger/tst_dumpers.cpp @@ -3398,6 +3398,14 @@ void tst_Dumpers::dumper_data() "{\n" " void run()\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" " BREAK;\n" " }\n" @@ -4375,15 +4383,16 @@ void tst_Dumpers::dumper_data() + MacLibCppProfile() + Check("p0", "(null)", "std::unique_ptr >") - + Check("p1", "32", "std::unique_ptr >") - + Check("p1.data", "32", "int") - + Check("p2", Pointer(), "std::unique_ptr >") - + CheckType("p2.data", "Foo") + + Check("p3", "\"ABC\"", "std::unique_ptr >"); - + Check("p3", "\"ABC\"", "std::unique_ptr >") - + Check("p3.data", "\"ABC\"", "std::string"); + + QTest::newRow("StdOnce") + << Data("#include \n", + "std::once_flag x; unused(&x);\n") + + Cxx11Profile() + + Check("x", "0", "std::once_flag"); QTest::newRow("StdSharedPtr") @@ -4401,17 +4410,12 @@ void tst_Dumpers::dumper_data() + MacLibCppProfile() + Check("pi", "32", "std::shared_ptr") - + Check("pi.data", "32", "int") + Check("pf", Pointer(), "std::shared_ptr") - + CheckType("pf.data", "Foo") + Check("ps", "\"ABC\"", "std::shared_ptr") - + Check("ps.data", "\"ABC\"", "std::string") + Check("wi", "32", "std::weak_ptr") - + Check("wi.data", "32", "int") + Check("wf", Pointer(), "std::weak_ptr") - + CheckType("wf.data", "Foo") + Check("ws", "\"ABC\"", "std::weak_ptr") - + Check("ws.data", "\"ABC\"", "std::string"); + + Check("ps", "\"ABC\"", "std::shared_ptr"); QTest::newRow("StdSharedPtr2") << Data("#include \n" @@ -4429,10 +4433,10 @@ void tst_Dumpers::dumper_data() + Check("inner.m_1", "0x1", "int *") + Check("inner.m_2", "0x2", "int *") + Check("inner.x", "3", "int") - + Check("a.data.m_0", "0x0", "int *") - + Check("a.data.m_1", "0x1", "int *") - + Check("a.data.m_2", "0x2", "int *") - + Check("a.data.x", "3", "int"); + + Check("a.m_0", "0x0", "int *") + + Check("a.m_1", "0x1", "int *") + + Check("a.m_2", "0x2", "int *") + + Check("a.x", "3", "int"); QTest::newRow("StdSet") << Data("#include \n", @@ -5587,13 +5591,9 @@ void tst_Dumpers::dumper_data() + Check("s", "(null)", "boost::shared_ptr") + Check("i", "43", "boost::shared_ptr") - + Check("i.weakcount", "1", "int") - + Check("i.usecount", "2", "int") - + Check("i.data", "43", "int") + Check("j", "43", "boost::shared_ptr") + Check("sl", "<1 items>", " boost::shared_ptr<@QStringList>") - + Check("sl.data", "<1 items>", "@QStringList") - + Check("sl.data.0", "[0]", "\"HUH!\"", "@QString"); + + Check("sl.0", "[0]", "\"HUH!\"", "@QString"); QTest::newRow("BoostGregorianDate") @@ -6389,7 +6389,8 @@ void tst_Dumpers::dumper_data() " root->appendRow(item);\n" "}\n") + 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") diff --git a/tests/auto/valgrind/memcheck/testapps/testapp.qbs b/tests/auto/valgrind/memcheck/testapps/testapp.qbs index 31178978d6b..375024c5007 100644 --- a/tests/auto/valgrind/memcheck/testapps/testapp.qbs +++ b/tests/auto/valgrind/memcheck/testapps/testapp.qbs @@ -8,5 +8,5 @@ QtcAutotest { targetName: testName // Test runner hardcodes the names of the executables destinationDirectory: project.buildDirectory + '/' + qtc.ide_bin_path + '/testapps/' + testName - files: "main.cpp" + files: sourceDirectory + "/main.cpp" }