Merge remote-tracking branch 'origin/2.8'

Conflicts:
	src/plugins/coreplugin/documentmanager.cpp

Change-Id: I6dc025bc0f31eb694c8d9e2dd4ea5cc888ee8a94
This commit is contained in:
Eike Ziller
2013-06-14 16:21:04 +02:00
427 changed files with 8639 additions and 4226 deletions

View File

@@ -17,7 +17,6 @@
****************************************************************************/
/*!
\contentspage{index.html}{Qt Creator}
\previouspage qtcreator-ui-text.html
\page coding-style.html
\nextpage qtcreator-api.html

View File

@@ -17,7 +17,6 @@
****************************************************************************/
/*!
\contentspage{index.html}{Qt Creator}
\page external-tool-spec.html
\nextpage coding-style.html

View File

@@ -17,7 +17,6 @@
****************************************************************************/
/*!
\contentspage{index.html}{Extending Qt Creator Manual}
\page qtcreator-api.html
\title Qt Creator API Reference

View File

@@ -17,7 +17,7 @@
****************************************************************************/
/*!
\page index.html
\page extending-index.html
\title Extending Qt Creator Manual
Qt Creator is a cross-platform integrated development environment (IDE)

View File

@@ -17,7 +17,6 @@
****************************************************************************/
/*!
\contentspage{index.html}{Qt Creator}
\previouspage external-tool-spec.html
\page qtcreator-documentation.html
\nextpage coding-style.html

View File

@@ -17,7 +17,6 @@
****************************************************************************/
/*!
\contentspage{index.html}{Qt Creator}
\previouspage external-tool-spec.html
\page qtcreator-ui-text.html
\nextpage coding-style.html

View File

@@ -105,6 +105,7 @@ Rectangle {
Transition {
from: "*"; to: "State1"
NumberAnimation {
easing.type: Easing.OutBounce
properties: "x,y";
duration: 1000
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 52 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 54 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.3 KiB

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 31 KiB

After

Width:  |  Height:  |  Size: 7.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 97 KiB

After

Width:  |  Height:  |  Size: 63 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 64 KiB

After

Width:  |  Height:  |  Size: 216 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 39 KiB

View File

@@ -61,15 +61,51 @@
It also applies for code in other compiled languages such as C,
FORTRAN, Ada.
For more information on the debugger modes, see
\l{Launching the Debugger in Different Modes}.
\section1 Supported Native Debugger Versions
Qt Creator supports essentially two native debuggers when working with
Qt Creator supports native debuggers when working with
compiled code. On most supported platforms, the GNU Symbolic Debugger
GDB can be used. On Microsoft Windows, when using the Microsoft tool chain
the Microsoft Console Debugger CDB, is needed. There is also an
incomplete experimental interface to LLDB on Mac OS and Linux available
when building \QC from source.
The following table summarizes the support for debugging C++ code:
\table
\header
\li Platform
\li Compiler
\li Native Debugger
\row
\li Linux
\li GCC, ICC
\li GDB
\row
\li Unix
\li GCC, ICC
\li GDB
\row
\li Mac OS X
\li GCC, Clang
\li Apple GDB, FSF GDB (experimental), LLDB (experimental)
\row
\li Windows/MinGW
\li GCC
\li GDB
\row
\li Windows/MSVC
\li Microsoft Visual C++ Compiler
\li Debugging Tools for Windows/CDB
\row
\li Maemo, MeeGo
\li GCC
\li GDB
\endtable
\section2 Supported GDB Versions
GDB comes in two varieties with common roots.
@@ -105,41 +141,16 @@
debugger engine. Specifically, it also uses compiled C++ code for the
debugging helper library.
The following table summarizes the support for debugging C++ code:
\section2 Supported LLDB Versions
\table
\header
\li Platform
\li Compiler
\li Native Debugger
\row
\li Linux
\li GCC, ICC
\li GDB
\row
\li Unix
\li GCC, ICC
\li GDB
\row
\li Mac OS X
\li GCC
\li Apple GDB, FSF GDB (experimental)
\row
\li Windows/MinGW
\li GCC
\li GDB
\row
\li Windows/MSVC
\li Microsoft Visual C++ Compiler
\li Debugging Tools for Windows/CDB
\row
\li Maemo, MeeGo
\li GCC
\li GDB
\endtable
The LLDB native debugger has similar functionality to the GDB debugger.
LLDB is the default debugger in Xcode on Mac OS X for supporting C++ on the
desktop. LLDB is typically used with the Clang compiler (even though you
can use it with GCC, too).
For more information on the debugger modes, see
\l{Launching the Debugger in Different Modes}.
You can use the LLDB version delivered with Xcode, but we recommend that you
build it from sources using Xcode. The minimal supported version is LLDB
300.99.
\omit
@@ -233,6 +244,10 @@
application to crash. For a workaround, see:
\l{http://bugreports.qt-project.org/browse/QTBUG-4962}{QTBUG-4962}.
\row
\li LLDB
\li An LLDB version is delivered with Xcode, but we recommend that
you build LLDB from sources using Xcode.
\endtable
\section1 Mapping Source Paths
@@ -336,4 +351,29 @@
\endlist
\section1 Setting Up Experimental LLDB Support
To use the experimental interface to LLDB, you must set up a kit that uses
the LLDB engine and select the kit for your project:
\list 1
\li Select \gui Tools > \gui Options > \gui {Build & Run} > \gui Kits.
\li Select an automatically created kit in the list, and then select
\gui Clone to create a copy of the kit.
\li In the \gui Debugger field, select \gui Edit to change the
automatically detected debugger to LLDB Engine.
\li In the \gui Engine field, select \gui {LLDB Engine}.
\li Select \gui Choose to set the path to the LLDB engine in the
\gui Binary field.
\li To use the debugger, add the kit in the \gui {Build Settings}
of the project.
\endlist
*/

View File

@@ -726,15 +726,17 @@
attach it to a running process, specify the process ID as a parameter for
the \c {-debug} option. To examine a core file, specify the file name.
\QC executes all the necessary steps, such as searching for
the binary that belongs to a core file.
the binary that belongs to a core file. To connect to a debug server,
specify the server location and port number.
For example:
\list
\li \c {C:\qtcreator\bin>qtcreator -debug 2000}
\li \c {C:\qtcreator\bin>qtcreator -debug core.2000}
\li \c {C:\qtcreator\bin>qtcreator -debug core=core.2000}
\li \c {C:\qtcreator\bin>qtcreator -debug some.exe,core=core}
\li \c {C:\qtcreator\bin>qtcreator -debug server=some.dot.com:4251}
\endlist

View File

@@ -73,6 +73,11 @@
to use for opening the file. If your files do not match the
predefined MIME types, you can edit the MIME types.
\li \l{Comparing Files}
You can use a diff editor to compare two versions of a file and
view the differences side-by-side in the \gui Edit mode.
\endlist
*/

View File

@@ -0,0 +1,89 @@
/****************************************************************************
**
** Copyright (c) 2013 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of Qt Creator
**
**
** GNU Free Documentation License
**
** Alternatively, this file may be used under the terms of the GNU Free
** Documentation License version 1.3 as published by the Free Software
** Foundation and appearing in the file included in the packaging of this
** file.
**
**
****************************************************************************/
// **********************************************************************
// NOTE: the sections are not ordered by their logical order to avoid
// reshuffling the file each time the index order changes (i.e., often).
// Run the fixnavi.pl script to adjust the links to the index order.
// **********************************************************************
/*!
\contentspage index.html
\previouspage creator-macros.html
\page creator-diff-editor.html
\nextpage creator-finding-overview.html
\title Comparing Files
You can use a diff editor from \QC to compare two text files. They can be
either versions of the same file or arbitrary files.
\image creator-diff-editor.png "Diff editor output in the Edit mode"
To compare files:
\list 1
\li Select \gui Tools > \gui Diff.
\li Select two files to compare.
\endlist
The differences are output in the \gui Edit mode. Color coding is used to
mark changed lines. By default, light red indicates lines that contain
removed text (painted a darker red) in the left pane and light green
indicates lines that contain added text (painted a darker green) in the
right pane.
To change the default colors, select \gui Tools > \gui Options >
\gui {Text Editor} > \gui {Font & Colors}. Create your own color scheme and
select new colors for the following options:
\list
\li \gui {Diff File Line} sets the color of the line that shows the
path and filename of the changed file.
\li \gui {Diff Context Line} sets the color of the line that shows
the number of hidden lines between changed lines.
\li \gui {Diff Source Line} sets the color of lines that contain removed
text.
\li \gui {Diff Source Character} sets the color that indicates removed
characters.
\li \gui {Diff Destination Line} sets the color of lines that contain
added text.
\li \gui {Diff Destination Character} sets the color that indicates
added characters.
\endlist
To only show text changes, select \gui {Ignore Whitespace}.
To expand the context for the changes, set the number of unchanged lines to
show in \gui {Context lines}. Set the value to -1 to show the whole file.
By default, the horizontal scroll bars in the left and right pane are
synchronized. To use them independently of each other, select the
\inlineimage qtcreator-synchronizefocus.png
(\gui {Synchronize Horizontal Scroll Bars}) button.
*/

View File

@@ -923,7 +923,7 @@
\contentspage index.html
\previouspage creator-editor-codepasting.html
\page creator-macros.html
\nextpage creator-finding-overview.html
\nextpage creator-diff-editor.html
\title Using Text Editing Macros

View File

@@ -24,7 +24,7 @@
/*!
\contentspage index.html
\previouspage creator-macros.html
\previouspage creator-diff-editor.html
\page creator-finding-overview.html
\nextpage creator-editor-finding.html

View File

@@ -100,8 +100,36 @@
\li Core plugin: override the selected UI color.
\row
\li -debug <PID-or-corefile>
\li Debugger plugin: attach to process ID or core file.
\li -debug <pid>
\li Debugger plugin: attach to the process with the given process ID.
\row
\li -debug <executable>[,kit=<kit>]
\li Debugger plugin: launch and debug the executable with the name
\c{executable}.
A \c{kit} can be specified to point to non-default debuggers
and sysroots.
\row
\li -debug [executable,]core=<corefile>[,kit=<kit>]
\li Debugger plugin: load the core file named \c{corefile}.
The parameter \c{executable} specifies the executable that
produced the core file.
If this parameter is omitted, \QC will attempt to reconstruct
it from the core file itself.
This will fail for paths with more than about 80 characters.
In such cases the \c{executable} parameter is mandatory.
A \c{kit} can be specified to point to non-default debuggers
and sysroots.
\row
\li -debug <executable>,server=<server:port>[,kit=<kit>]
\li Debugger plugin: attach to a debug server running on the port
\c{port} on the server \c{server}. The parameter \c{executable}
specifies a local copy of the executable the remote debug server is
manipulating.
A \c{kit} can be specified to point to non-default debuggers
and sysroots.
\row
\li -wincrashevent <event-handle>

View File

@@ -281,6 +281,10 @@
\li \gui Analyzer - Errors encountered while running the
\l{Analyzing Code}{Valgrind code analysis tools}.
\li \gui {Bar Descriptor} - Errors and warnings encountered when using
the BlackBerry 10 BAR descriptor editor to customize the appearance
and behavior of an application.
\li \gui {Build System} - Errors and warnings encountered during a
build.

View File

@@ -192,6 +192,11 @@
\image qtcreator-vcs-diff.png
With Git, the diff is displayed side-by-side in a \l{Comparing Files}
{diff editor} by default. To use the old diff view instead, select
\gui Tools > \gui Options > \gui {Version Control} > \gui Git, and deselect
the \gui {Show diff side-by-side} option.
\section2 Viewing Versioning History and Change Details
Display the versioning history of a file by selecting \gui{Log}
@@ -257,12 +262,12 @@
\list
\li \gui Git > \gui {Current File} > \gui{Undo Unstaged Changes} reverts
all changes and resets the working directory to the state of the
all changes and resets the current file to the state of the
index.
\li \gui Git > \gui {Current File} > \gui {Undo Uncommitted Changes}
reverts all changes, discarding the
index. This returns your working copy to the state it was in right
index. This returns the current file to the state it was in right
after the last commit.
\li \gui Git > \gui {Local Repository} > \gui Reset opens a dialog
@@ -381,14 +386,20 @@
select \gui Tools > \gui Git > \gui {Local Repository} > \gui Clean to clean
the repository.
To show commits, select \gui Tools > \gui Git > \gui {Show Commit} and
select a commit to view. Enter the SHA-1 or reference of the commit in the
\gui Change field.
To apply latest changes to the last commit, select \gui Tools > \gui Git >
\gui {Local Repository} > \gui {Amend Last Commit}. You can also edit the
commit message.
To amend an earlier comment in a series of related commits, select
\gui Tools > \gui Git > \gui {Local Repository} >
\gui {Fixup Previous Commit}. This operation is done using interactive
rebase. In case of conflicts, a merge tool is suggested.
To change a series of commits in the local repository, select \gui Tools >
\gui Git > \gui {Local Repository} > \gui {Interactive Rebase}. You can
reorder or discard commits, squash them into a single commit, or edit the
commit messages.
The following sections describe how to manage local and remote branches,
apply patches, and use stashes.
@@ -415,6 +426,9 @@
\row
\li \gui{Remove}
\li Remove a local branch. You cannot delete remote branches.
\row
\li \gui Rename
\li Rename a local branch.
\row
\li \gui{Checkout}
\li Check out the selected branch and make it current. You can stash
@@ -458,13 +472,21 @@
display or delete them, select \gui Stashes.
To save a snapshot of your current work under a name for later reference,
select \gui {Stash Snapshot}. The working copy is unchanged. For example, if
select \gui {Take Snapshot}. The working copy is unchanged. For example, if
you want to try something and find out later that it does not work, you can
discard the changes and return to the state of the snapshot.
To remove a single stashed state from the stash list and apply it on top of
the current working tree state, select \gui {Stash Pop}.
\section3 Applying Actions to Commits
To browse a directory or the commit history and to apply actions on the
commits, select \gui Tools > \gui Git > \gui {Actions on Commits}. You can
checkout, revert, or cherry-pick commits or view them in the diff editor.
\image creator-git-commit-actions.png "Select a Git Commit dialog"
\section3 Working with Remote Repositories
In addition to the standard version control system functions, you can
@@ -487,6 +509,9 @@
\header
\li Menu Item
\li Description
\row
\li \gui{Refresh}
\li Refresh the list of remote repositories.
\row
\li \gui{Add}
\li Add a new remote repository.
@@ -494,12 +519,13 @@
\li \gui{Fetch}
\li Fetch all the branches and change information from a remote
repository.
\row
\li \gui Push
\li Push committed changes to the remote repository.
\row
\li \gui{Remove}
\li Remove a remote repository.
\row
\li \gui{Refresh}
\li Refresh the list of remote repositories.
\endtable
\section4 Using Git with Subversion
@@ -520,8 +546,12 @@
\image qtcreator-gerrit-options.png
You can see the same information about each change as in the Gerrit
web interface.
To push committed changes to Gerrit, select \gui Tools > \gui Git >
\gui {Remote Repository} > \gui {Push to Gerrit}.
To view the same information about each change as in the Gerrit
web interface, select \gui Tools > \gui Git > \gui {Remote Repository} >
\gui Gerrit.
\image qtcreator-gerrit.png

View File

@@ -35,7 +35,7 @@
\list 1
\li On the \gui Welcome page, select \gui Examples (1).
\li In the \gui Welcome mode, select \gui Examples (1).
\image qtcreator-gs-build-example-open.png "Selecting an example"

View File

@@ -67,15 +67,6 @@
\image creator-qbs-project.png
\li Select \gui Build > \gui {Build Project} to build the executable, so
that you can specify it in the run settings of the project.
\li Select \gui Projects > \gui {Run}, and specify the executable in the
\gui Command field. This allows you to run it directly from \QC.
This will happen automatically in a future release.
\image creator-run-settings-qbs.png
\li Click the
\inlineimage qtcreator-run.png
(\gui Run) button to run the application.

View File

@@ -89,8 +89,8 @@
if they are installed on the development PC, but were not detected
automatically. For more information, see \l{Adding Compilers}.
\li In the \gui Debugger field, select \gui Manage to automatically
detect a suitable debugger or to edit the currently selected
\li In the \gui Debugger field, select \gui Auto-detect to automatically
detect a suitable debugger or \gui Edit to edit the currently selected
debugger. For more information, see \l{Selecting the Debugger}.
\li In the \gui {Qt version} field, select the Qt version to use for
@@ -111,18 +111,20 @@
\section1 Selecting the Debugger
To automatically detect a suitable debugger in the \gui Debugger field,
select \gui Manage > \gui {Auto-detect}. This should work for the CDB engine
select \gui {Auto-detect}. This should work for the CDB engine
and for the GDB engine for local debugging on Linux or Mac OS.
To edit the selected debugger, select \gui Manage > \gui Edit. In the
To edit the selected debugger, select \gui Edit. In the
\gui {Debugger for} dialog, specify the type of debugger to use
(\gui {GDB Engine} or \gui {CDB Engine}) and the path to the debugger
binary.
(\gui {GDB Engine}, \gui {CDB Engine}, or \gui {LLDB Engine}) and the path
to the debugger binary:
For the \gui {CDB Engine} (Windows only), specify the path to the Windows
\list
\li For the \gui {CDB Engine} (Windows only), specify the path to the Windows
Console Debugger executable.
For the \gui {GDB Engine}, specify the path to the GDB executable. The
\li For the \gui {GDB Engine}, specify the path to the GDB executable. The
executable must be built with Python scripting support enabled
(except when debugging on Mac OS). The options you have depend on the
development and target platform:
@@ -138,4 +140,8 @@
\endlist
\li For the \gui {LLDB Engine} (experimental), specify the path to the LLDB
executable.
\endlist
*/

View File

@@ -213,6 +213,7 @@
\li \l{Using Qt Quick Toolbars}
\li \l{Pasting and Fetching Code Snippets}
\li \l{Using Text Editing Macros}
\li \l{Comparing Files}
\endlist
\li \l{Finding}
\list

View File

@@ -34,7 +34,7 @@
\l {http://qt-project.org/doc/qt-5.0/qtquick/qtquick-index.html}{Qt Quick}.
This tutorial describes how to use \QC to implement Qt states and transitions. We use
\l{http://qt-project.org/doc/qt-5.0/qtquick/quick-animation.html}{Qt example code} to
\l{http://qt-project.org/doc/qt-5.0/qtquick/animation.html}{Qt example code} to
create an application that displays a Qt logo that moves between three rectangles on the
page when you click them.
@@ -72,7 +72,7 @@
\li Review the project settings, and click \gui{Finish} (on Windows and
Linux) or \gui Done (on Mac OS) to create the project.
\li Press \key {Ctrl+R} (or \key {Cmd+R})to run the application.
\li Press \key {Ctrl+R} (or \key {Cmd+R}) to run the application.
\endlist
@@ -224,7 +224,7 @@
\li In the \gui Margin field, select 10 for the right anchor and 0
for the vertical center anchor.
\li In the code editor,add a pointer to a clicked expression to the
\li In the code editor, add a pointer to a clicked expression to the
mouse area. The following expression sets the state to
\e State1:

View File

@@ -4,6 +4,7 @@ Product {
name: "QtComponents"
Group {
name: "Resources"
qbs.install: true
qbs.installDir: (qbs.targetOS == "windows" ? "lib/qtcreator" : project.ide_library_path)
+ "/qtcomponents"

View File

@@ -204,6 +204,7 @@ Project {
]
Group {
name: "qtcreator.sh"
condition: qbs.targetPlatform.indexOf("unix") != -1 && qbs.targetOS != "mac"
files: "bin/qtcreator.sh"
qbs.install: true
@@ -211,17 +212,19 @@ Project {
}
Group {
condition: qbs.targetPlatform.indexOf("unix") != -1
files: [
"src/shared/qtlockedfile/qtlockedfile_unix.cpp"
]
name: "QtLockedFile_unix"
condition: qbs.targetPlatform.indexOf("unix") != -1
files: [
"src/shared/qtlockedfile/qtlockedfile_unix.cpp"
]
}
Group {
condition: qbs.targetOS == "windows"
files: [
"src/shared/qtlockedfile/qtlockedfile_win.cpp"
]
name: "QtLockedFile_win"
condition: qbs.targetOS == "windows"
files: [
"src/shared/qtlockedfile/qtlockedfile_win.cpp"
]
}
Group {

View File

@@ -103,7 +103,7 @@ def listOfLocals(varList):
block = frame.block()
#warn("BLOCK: %s " % block)
except RuntimeError, error:
warn("BLOCK IN FRAME NOT ACCESSIBLE: %s" % error)
#warn("BLOCK IN FRAME NOT ACCESSIBLE: %s" % error)
return []
except:
warn("BLOCK NOT ACCESSIBLE FOR UNKNOWN REASONS")
@@ -400,7 +400,7 @@ def bbsetup(args = ''):
result += '{type="%s",formats="%s"},' % (key, value)
result += ']'
#result += ',namespace="%s"' % qqNs
result += ',hasInferiorThreadList="%s"' % int(hasInferiorThreadList())
print result
return result
registerCommand("bbsetup", bbsetup)
@@ -472,6 +472,9 @@ def childAt(value, index):
# them transparently.
return value
def fieldAt(type, index):
return type.fields()[index]
#gdb.Value.child = impl_Value_child
@@ -569,17 +572,6 @@ def hasPlot():
return os.path.isfile(fileName) and os.access(fileName, os.X_OK)
#
# Threads
#
def hasInferiorThreadList():
#return False
try:
a = gdb.inferiors()[0].threads()
return True
except:
return False
#
# VTable
#
@@ -1350,13 +1342,6 @@ class Dumper:
self.useDynamicType = True
self.expandedINames = {}
self.charType_ = None
self.intType_ = None
self.sizetType_ = None
self.charPtrType_ = None
self.voidType_ = None
self.voidPtrType_ = None
def __init__(self, args):
self.defaultInit()
@@ -1437,12 +1422,6 @@ class Dumper:
if fullUpdateNeeded and not self.tooltipOnly and not self.noLocals:
locals = listOfLocals(varList)
if "autotest" in options:
for item in listOfLocals([]):
self.expandedINames.add(item.iname)
self.expandedINames.discard("")
#warn("EXPANDED: %s" % self.expandedINames)
# Take care of the return value of the last function call.
if len(resultVarName) > 0:
try:
@@ -1567,29 +1546,19 @@ class Dumper:
self.putNumChild(0)
def intType(self):
if self.intType_ is None:
self.intType_ = self.lookupType('int')
return self.intType_
return self.lookupType('int')
def charType(self):
if self.charType_ is None:
self.charType_ = self.lookupType('char')
return self.charType_
return self.lookupType('char')
def sizetType(self):
if self.sizetType_ is None:
self.sizetType_ = self.lookupType('size_t')
return self.sizetType_
return self.lookupType('size_t')
def charPtrType(self):
if self.charPtrType_ is None:
self.charPtrType_ = self.lookupType('char*')
return self.charPtrType_
return self.lookupType('char*')
def voidPtrType(self):
if self.voidPtrType_ is None:
self.voidType_ = self.lookupType('void*')
return self.voidPtrType_
return self.lookupType('void*')
def voidPtrSize(self):
return self.voidPtrType().sizeof
@@ -1683,24 +1652,12 @@ class Dumper:
if limit is None:
return size
if limit == 0:
#return min(size, qqStringCutOff)
return min(size, 100)
return min(size, qqStringCutOff)
return min(size, limit)
def putName(self, name):
self.put('name="%s",' % name)
def putMapName(self, value):
ns = qtNamespace()
if str(value.type) == ns + "QString":
self.put('key="%s",' % encodeString(value))
self.put('keyencoded="%s",' % Hex4EncodedLittleEndian)
elif str(value.type) == ns + "QByteArray":
self.put('key="%s",' % self.encodeByteArray(value))
self.put('keyencoded="%s",' % Hex2EncodedLatin1)
else:
self.put('name="%s",' % value)
def isExpanded(self):
#warn("IS EXPANDED: %s in %s: %s" % (self.currentIName,
# self.expandedINames, self.currentIName in self.expandedINames))
@@ -2044,6 +2001,22 @@ class Dumper:
self.putNumChild(0)
return
if format == 6:
# Explicitly requested formatting as array of 10 items.
self.putType(typeName)
self.putItemCount(10)
self.putNumChild(10)
self.putArrayData(innerType, value, 10)
return
if format == 7:
# Explicitly requested formatting as array of 1000 items.
self.putType(typeName)
self.putItemCount(1000)
self.putNumChild(1000)
self.putArrayData(innerType, value, 1000)
return
if innerType.code == MethodCode or innerType.code == FunctionCode:
# A function pointer with format None.
self.putValue(str(value))
@@ -2304,36 +2277,61 @@ class Dumper:
#
#######################################################################
def threadnames(arg):
def threadname(arg):
try:
e = gdb.selected_frame()
except:
return
d = Dumper("")
out = ""
maximalStackDepth = int(arg)
ns = qtNamespace()
while True:
maximalStackDepth -= 1
if maximalStackDepth < 0:
break
e = e.older()
if e == None or e.name() == None:
break
if e.name() == ns + "QThreadPrivate::start" \
or e.name() == "_ZN14QThreadPrivate5startEPv@4":
try:
thrptr = e.read_var("thr").dereference()
obtype = lookupType(ns + "QObjectPrivate").pointer()
d_ptr = thrptr["d_ptr"]["d"].cast(obtype).dereference()
try:
objectName = d_ptr["objectName"]
except: # Qt 5
p = d_ptr["extraData"]
if not isNull(p):
objectName = p.dereference()["objectName"]
if not objectName is None:
data, size, alloc = d.stringData(objectName)
if size > 0:
s = d.readRawMemory(data, 2 * size)
thread = gdb.selected_thread()
inner = '{valueencoded="';
inner += str(Hex4EncodedLittleEndianWithoutQuotes)+'",id="'
inner += str(thread.num) + '",value="'
inner += s
#inner += d.encodeString(objectName)
inner += '"},'
out += inner
except:
pass
return out
def threadnames(arg):
out = '['
oldthread = gdb.selected_thread()
try:
inferior = selectedInferior()
for thread in inferior.threads():
maximalStackDepth = int(arg)
thread.switch()
e = gdb.selected_frame ()
while True:
maximalStackDepth -= 1
if maximalStackDepth < 0:
break
e = e.older()
if e == None or e.name() == None:
break
if e.name() == ns + "QThreadPrivate::start":
try:
thrptr = e.read_var("thr").dereference()
obtype = lookupType(ns + "QObjectPrivate").pointer()
d_ptr = thrptr["d_ptr"]["d"].cast(obtype).dereference()
objectName = d_ptr["objectName"]
out += '{valueencoded="';
out += str(Hex4EncodedLittleEndianWithoutQuotes)+'",id="'
out += str(thread.num) + '",value="'
out += encodeString(objectName)
out += '"},'
except:
pass
out += threadname(arg)
except:
pass
oldthread.switch()

View File

@@ -8,11 +8,24 @@ import select
import sys
import subprocess
proc = subprocess.Popen(args=[sys.argv[1], '-P'], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
(path, error) = proc.communicate()
if error.startswith('lldb: invalid option -- P'):
sys.stdout.write('msg=\'Could not run "%s -P". Trying to find lldb.so from Xcode.\'@\n' % sys.argv[1])
proc = subprocess.Popen(args=['xcode-select', '--print-path'],
stdout=subprocess.PIPE, stderr=subprocess.PIPE)
(path, error) = proc.communicate()
if len(error):
path = '/Applications/Xcode.app/Contents/SharedFrameworks/LLDB.framework/Versions/A/Resources/Python/'
sys.stdout.write('msg=\'Could not run "xcode-select --print-path"@\n')
sys.stdout.write('msg=\'Using hardcoded fallback at %s\'@\n' % path)
else:
path = path.strip() + '/../SharedFrameworks/LLDB.framework/Versions/A/Resources/Python/'
sys.stdout.write('msg=\'Using fallback at %s\'@\n' % path)
proc = subprocess.Popen(args=[sys.argv[1], "-P"], stdout=subprocess.PIPE)
path = proc.stdout.read().strip()
#sys.path.append(path)
sys.path.insert(1, path)
sys.path.insert(1, path.strip())
import lldb
@@ -68,6 +81,20 @@ def isSimpleType(typeobj):
#warn("TYPECLASS: %s" % typeClass)
return typeClass == lldb.eTypeClassBuiltin
def call2(value, func, args):
# args is a tuple.
arg = ','.join(args)
warn("CALL: %s -> %s(%s)" % (value, func, arg))
type = value.type.name
exp = "((%s*)%s)->%s(%s)" % (type, value.address, func, arg)
warn("CALL: %s" % exp)
result = value.CreateValueFromExpression('$tmp', exp)
warn(" -> %s" % result)
return result
def call(value, func, *args):
return call2(value, func, args)
#######################################################################
#
# Helpers
@@ -97,7 +124,7 @@ def stripForFormat(typeName):
return qqStripForFormat[typeName]
stripped = ""
inArray = 0
for c in stripClassTag(typeName):
for c in typeName:
if c == '<':
break
if c == ' ':
@@ -136,7 +163,7 @@ def registerDumper(function):
pass
def warn(message):
print '\nWARNING="%s",\n' % message.encode("latin1").replace('"', "'")
print '\n\nWARNING="%s",\n' % message.encode("latin1").replace('"', "'")
def showException(msg, exType, exValue, exTraceback):
warn("**** CAUGHT EXCEPTION: %s ****" % msg)
@@ -279,17 +306,23 @@ def impl_SBValue__int__(self):
def impl_SBValue__long__(self):
return int(self.GetValue(), 0)
def impl_SBValue__getitem__(self, name):
if self.GetType().IsPointerType() and isinstance(name, int):
innertype = self.Dereference().GetType()
address = self.GetValueAsUnsigned() + name * innertype.GetByteSize()
address = address & 0xFFFFFFFFFFFFFFFF # Force unsigned
return self.CreateValueFromAddress(None, address, innertype)
return self.GetChildMemberWithName(name)
def impl_SBValue__getitem__(value, index):
if isinstance(index, int):
type = value.GetType()
if type.IsPointerType():
innertype = value.Dereference().GetType()
address = value.GetValueAsUnsigned() + index * innertype.GetByteSize()
address = address & 0xFFFFFFFFFFFFFFFF # Force unsigned
return value.CreateValueFromAddress(None, address, innertype)
return value.GetChildAtIndex(index)
return value.GetChildMemberWithName(index)
def childAt(value, index):
return value.GetChildAtIndex(index)
def fieldAt(type, index):
return type.GetFieldAtIndex(index)
lldb.SBValue.__add__ = impl_SBValue__add__
lldb.SBValue.__sub__ = impl_SBValue__sub__
lldb.SBValue.__le__ = impl_SBValue__le__
@@ -309,6 +342,9 @@ lldb.SBType.code = lambda self: self.GetTypeClass()
lldb.SBType.sizeof = property(lambda self: self.GetByteSize())
lldb.SBType.strip_typedefs = lambda self: self.GetCanonicalType()
lldb.SBType.__orig__str__ = lldb.SBType.__str__
lldb.SBType.__str__ = lldb.SBType.GetName
def simpleEncoding(typeobj):
code = typeobj.GetTypeClass()
size = typeobj.sizeof
@@ -370,11 +406,12 @@ class Children:
self.childNumChild = childNumChild
try:
if not addrBase is None and not addrStep is None:
self.d.put('addrbase="0x%x",' % long(addrBase))
self.d.put('addrstep="0x%x",' % long(addrStep))
self.d.put('addrbase="0x%x",' % int(addrBase))
self.d.put('addrstep="0x%x",' % int(addrStep))
self.printsAddress = False
except:
warn("ADDRBASE: %s" % addrBase)
warn("ADDRSTEP: %s" % addrStep)
#warn("CHILDREN: %s %s %s" % (numChild, childType, childNumChild))
def __enter__(self):
@@ -408,6 +445,18 @@ class Children:
return True
class NoAddress:
def __init__(self, d):
self.d = d
def __enter__(self):
self.savedPrintsAddress = self.d.currentPrintsAddress
self.d.currentPrintsAddress = False
def __exit__(self, exType, exValue, exTraceBack):
self.d.currentPrintsAddress = self.savedPrintsAddress
class SubItem:
def __init__(self, d, component):
@@ -427,6 +476,7 @@ class SubItem:
if isinstance(self.name, str):
self.d.put('name="%s",' % self.name)
self.savedIName = self.d.currentIName
self.savedCurrentAddress = self.d.currentAddress
self.savedValue = self.d.currentValue
self.savedValuePriority = self.d.currentValuePriority
self.savedValueEncoding = self.d.currentValueEncoding
@@ -456,6 +506,8 @@ class SubItem:
self.d.put('value="%s",' % self.d.currentValue)
except:
pass
if not self.d.currentAddress is None:
self.d.put(self.d.currentAddress)
self.d.put('},')
self.d.currentIName = self.savedIName
self.d.currentValue = self.savedValue
@@ -463,6 +515,7 @@ class SubItem:
self.d.currentValueEncoding = self.savedValueEncoding
self.d.currentType = self.savedType
self.d.currentTypePriority = self.savedTypePriority
self.d.currentAddress = self.savedCurrentAddress
return True
class Dumper:
@@ -486,6 +539,9 @@ class Dumper:
self.autoDerefPointers = True
self.useDynamicType = True
self.useFancy = True
self.formats = {}
self.typeformats = {}
self.currentAddress = None
self.currentIName = None
self.currentValuePriority = -100
@@ -592,12 +648,14 @@ class Dumper:
def put(self, stuff):
sys.stdout.write(stuff)
def putField(self, name, value):
self.put('%s="%s",' % (name, value))
def currentItemFormat(self):
#format = self.formats.get(self.currentIName)
#if format is None:
# format = self.typeformats.get(stripForFormat(str(self.currentType)))
#return format
return 0
format = self.formats.get(self.currentIName)
if format is None:
format = self.typeformats.get(stripForFormat(str(self.currentType)))
return format
def isMovableType(self, type):
if type.code == PointerCode:
@@ -645,6 +703,9 @@ class Dumper:
else:
self.putValue('<%s items>' % count)
def putName(self, name):
self.put('name="%s",' % name)
def isExpanded(self):
#warn("IS EXPANDED: %s in %s: %s" % (self.currentIName,
# self.expandedINames, self.currentIName in self.expandedINames))
@@ -664,8 +725,11 @@ class Dumper:
return True
def putPlotData(self, type, base, n, plotFormat):
warn("PLOTDATA: %s %s" % (type, n))
if self.isExpanded():
self.putArrayData(type, base, n)
self.putValue(self.currentValue)
self.putField("plottable", "0")
def putArrayData(self, type, base, n,
childNumChild = None, maxNumChild = 10000):
@@ -676,6 +740,14 @@ class Dumper:
for i in self.childRange():
self.putSubItem(i, (base + i).dereference())
def parseAndEvalute(self, expr):
return expr
def putCallItem(self, name, value, func, *args):
result = call2(value, func, args)
with SubItem(self, name):
self.putItem(result)
def childRange(self):
if self.currentMaxNumChild is None:
return xrange(0, self.currentNumChild)
@@ -689,7 +761,8 @@ class Dumper:
self.putFields(value)
def lookupType(self, name):
#warn("LOOKUP: %s" % self.target.FindFirstType(name))
#warn("LOOKUP TYPE NAME: %s" % name)
#warn("LOOKUP RESULT: %s" % self.target.FindFirstType(name))
return self.target.FindFirstType(name)
def setupInferior(self, args):
@@ -789,20 +862,25 @@ class Dumper:
n = thread.GetNumFrames()
if n > 4:
n = 4
firstUsable = None
for i in xrange(n):
frame = thread.GetFrameAtIndex(i)
lineEntry = frame.GetLineEntry()
line = lineEntry.GetLine()
usable = line != 0
if usable and not firstUsable:
firstUsable = i
result += '{pc="0x%x"' % frame.GetPC()
result += ',level="%d"' % frame.idx
result += ',addr="0x%x"' % frame.GetPCAddress().GetLoadAddress(self.target)
result += ',func="%s"' % frame.GetFunctionName()
result += ',line="%d"' % lineEntry.GetLine()
result += ',line="%d"' % line
result += ',fullname="%s"' % fileName(lineEntry.file)
result += ',usable="1"'
result += ',usable="%d"' % usable
result += ',file="%s"},' % fileName(lineEntry.file)
hasmore = '0'
result += '],hasmore="%s"},' % hasmore
if not firstUsable:
firstUsable = 0
result += '],hasmore="0",first-usable="%s"},' % firstUsable
self.report(result)
def putType(self, type, priority = 0):
@@ -863,15 +941,25 @@ class Dumper:
def putSubItem(self, component, value, tryDynamic=True):
if not value.IsValid():
warn("INVALID")
warn("INVALID SUBITEM")
return
with SubItem(self, component):
self.putItem(value, tryDynamic)
def putAddress(self, addr):
if self.currentPrintsAddress:
try:
self.currentAddress = 'addr="0x%s",' % int(addr)
except:
pass
def putItem(self, value, tryDynamic=True):
#value = value.GetDynamicValue(lldb.eDynamicCanRunTarget)
typeName = value.GetTypeName()
if tryDynamic:
self.putAddress(value.address)
# Handle build-in LLDB visualizers if wanted.
if self.useLldbDumpers and value.GetTypeSynthetic().IsValid():
# FIXME: print "official" summary?
@@ -900,6 +988,11 @@ class Dumper:
# Our turf now.
value.SetPreferSyntheticValue(False)
# Arrays
if value.GetType().GetTypeClass() == lldb.eTypeClassArray:
qdump____c_style_array__(self, value)
return
# References
if value.GetType().IsReferenceType():
type = value.GetType().GetDereferencedType().GetPointerType()
@@ -1013,7 +1106,6 @@ class Dumper:
self.reportVariables()
def reportRegisters(self, _ = None):
return
if self.process is None:
self.report('process="none"')
else:
@@ -1138,6 +1230,12 @@ class Dumper:
elif bpType == BreakpointAtMain:
bpNew = self.target.BreakpointCreateByName(
"main", self.target.GetExecutable().GetFilename())
elif bpType == BreakpointAtThrow:
bpNew = self.target.BreakpointCreateForException(
lldb.eLanguageTypeC_plus_plus, False, True)
elif bpType == BreakpointAtCatch:
bpNew = self.target.BreakpointCreateForException(
lldb.eLanguageTypeC_plus_plus, True, False)
else:
warn("UNKNOWN TYPE")
bpNew.SetIgnoreCount(int(args["ignorecount"]))
@@ -1338,16 +1436,19 @@ class Dumper:
result += ',contents="%s"}' % binascii.hexlify(contents)
self.report(result)
def findValueByExpression(self, exp):
# FIXME: Top level-only for now.
frame = self.currentFrame()
value = frame.FindVariable(exp)
return value
def assignValue(self, args):
error = lldb.SBError()
exp = binascii.unhexlify(args['exp'])
value = binascii.unhexlify(args['value'])
warn("EXP: %s" % exp)
warn("VALUE: %s" % value)
lhs = self.dummyValue.CreateValueFromExpression("$$lhs", exp)
rhs = self.dummyValue.CreateValueFromExpression("$$rhs", value)
warn("LHS: %s" % lhs)
warn("RHS: %s" % rhs)
#lhs.SetData(rhs.GetData())
lhs = self.findValueByExpression(exp)
lhs.SetValueFromCString(value, error)
self.reportError(error)
self.reportVariables()
def importDumpers(self, _ = None):
@@ -1447,3 +1548,4 @@ if len(sys.argv) > 2:
testit()
else:
doit()

View File

@@ -18,54 +18,6 @@ movableTypes = set([
"QXmlStreamNotationDeclaration", "QXmlStreamEntityDeclaration"
])
# Compatibility with earlier versions
Dumper.encodeByteArray = \
lambda d, value, limit = None: qEncodeByteArray(d, value, limit)
Dumper.byteArrayData = \
lambda d, value: qByteArrayData(d, value)
Dumper.putByteArrayValue = \
lambda d, value: qPutByteArrayValue(d, value)
Dumper.encodeString = \
lambda d, value, limit = None: qString(d, value, limit)
Dumper.stringData = \
lambda d, value: qStringData(d, value)
Dumper.putStringValue = \
lambda d, value: qPutStringValue(d, value)
def mapForms():
return "Normal,Compact"
def arrayForms():
if hasPlot():
return "Normal,Plot"
return "Normal"
def mapCompact(format, keyType, valueType):
if format == 2:
return True # Compact.
return isSimpleType(keyType) and isSimpleType(valueType)
def qdump__QAtomicInt(d, value):
d.putValue(value["_q_value"])
d.putNumChild(0)
def qdump__QBasicAtomicInt(d, value):
d.putValue(value["_q_value"])
d.putNumChild(0)
def qdump__QBasicAtomicPointer(d, value):
d.putType(value.type)
p = cleanAddress(value["_q_value"])
d.putValue(p)
d.putPointerValue(value.address)
d.putNumChild(p)
if d.isExpanded():
with Children(d):
d.putItem(value["_q_value"])
def qByteArrayData(d, value):
private = value['d'].dereference()
checkRef(private['ref'])
@@ -73,13 +25,11 @@ def qByteArrayData(d, value):
alloc = int(private['alloc'])
try:
# Qt 5. Will fail on Qt 4 due to the missing 'offset' member.
offset = int(private['offset'])
addr = d.addressOf(private) + offset
data = createPointerValue(value, addr, d.charType())
return data, size, alloc
addr = d.addressOf(private) + int(private['offset'])
except:
# Qt 4:
return private['data'], size, alloc
addr = private['data']
return createPointerValue(value, addr, d.charType()), size, alloc
qStringData = qByteArrayData
@@ -109,6 +59,91 @@ def qPutByteArrayValue(d, value):
def qPutStringValue(d, value):
d.putValue(qEncodeString(d, value), Hex4EncodedLittleEndian)
def mapForms():
return "Normal,Compact"
def arrayForms():
if hasPlot():
return "Normal,Plot"
return "Normal"
def qMapCompact(format, keyType, valueType):
if format == 2:
return True # Compact.
return isSimpleType(keyType) and isSimpleType(valueType)
def qPutMapName(d, value):
if str(value.type) == d.ns + "QString":
d.put('key="%s",' % d.encodeString(value))
d.put('keyencoded="%s",' % Hex4EncodedLittleEndian)
elif str(value.type) == d.ns + "QByteArray":
d.put('key="%s",' % d.encodeByteArray(value))
d.put('keyencoded="%s",' % Hex2EncodedLatin1)
else:
if lldbLoaded:
d.put('name="%s",' % value.GetValue())
else:
d.put('name="%s",' % value)
Dumper.encodeByteArray = qEncodeByteArray
Dumper.byteArrayData = qByteArrayData
Dumper.putByteArrayValue = qPutByteArrayValue
Dumper.encodeString = qEncodeString
Dumper.stringData = qStringData
Dumper.putStringValue = qPutStringValue
Dumper.putMapName = qPutMapName
Dumper.isMapCompact = \
lambda d, keyType, valueType: qMapCompact(d.currentItemFormat(), keyType, valueType)
def tryPutObjectNameValue(d, value):
try:
# Is this derived from QObject?
dd = value["d_ptr"]["d"]
privateType = d.lookupType(d.ns + "QObjectPrivate")
staticMetaObject = value["staticMetaObject"]
d_ptr = dd.cast(privateType.pointer()).dereference()
objectName = None
try:
objectName = d_ptr["objectName"]
except: # Qt 5
p = d_ptr["extraData"]
if not isNull(p):
objectName = p.dereference()["objectName"]
if not objectName is None:
data, size, alloc = d.stringData(objectName)
if size > 0:
str = d.readRawMemory(data, 2 * size)
d.putValue(str, Hex4EncodedLittleEndian, 1)
except:
pass
Dumper.tryPutObjectNameValue = tryPutObjectNameValue
############################################################################################
def qdump__QAtomicInt(d, value):
d.putValue(value["_q_value"])
d.putNumChild(0)
def qdump__QBasicAtomicInt(d, value):
d.putValue(value["_q_value"])
d.putNumChild(0)
def qdump__QBasicAtomicPointer(d, value):
d.putType(value.type)
p = cleanAddress(value["_q_value"])
d.putValue(p)
d.putPointerValue(value.address)
d.putNumChild(p)
if d.isExpanded():
with Children(d):
d.putItem(value["_q_value"])
def qform__QByteArray():
return "Inline,As Latin1 in Separate Window,As UTF-8 in Separate Window"
@@ -252,12 +287,14 @@ def qdump__QModelIndex(d, value):
def qdump__QDate(d, value):
jd = value["jd"]
jd = int(value["jd"])
if int(jd):
d.putValue(jd, JulianDate)
d.putNumChild(1)
if d.isExpanded():
qt = d.ns + "Qt::"
if lldbLoaded:
qt += "DateFormat::" # FIXME: Bug?...
# FIXME: This improperly uses complex return values.
with Children(d):
d.putCallItem("toString", value, "toString", qt + "TextDate")
@@ -277,6 +314,8 @@ def qdump__QTime(d, value):
d.putNumChild(1)
if d.isExpanded():
qt = d.ns + "Qt::"
if lldbLoaded:
qt += "DateFormat::" # FIXME: Bug?...
# FIXME: This improperly uses complex return values.
with Children(d):
d.putCallItem("toString", value, "toString", qt + "TextDate")
@@ -297,15 +336,17 @@ def qdump__QDateTime(d, value):
except:
d.putPlainChildren(value)
return
mds = p["time"]["mds"]
if int(mds) >= 0:
d.putValue("%s/%s" % (p["date"]["jd"], mds),
mds = int(p["time"]["mds"])
if mds >= 0:
d.putValue("%s/%s" % (int(p["date"]["jd"]), mds),
JulianDateAndMillisecondsSinceMidnight)
d.putNumChild(1)
if d.isExpanded():
# FIXME: This improperly uses complex return values.
with Children(d):
qt = d.ns + "Qt::"
if lldbLoaded:
qt += "DateFormat::" # FIXME: Bug?...
d.putCallItem("toTime_t", value, "toTime_t")
d.putCallItem("toString", value, "toString", qt + "TextDate")
d.putCallItem("(ISO)", value, "toString", qt + "ISODate")
@@ -347,7 +388,7 @@ def qdump__QFile(d, value):
d.putNumChild(1)
if d.isExpanded():
with Children(d):
base = value.type.fields()[0].type
base = fieldAt(value.type, 0).type
d.putSubItem("[%s]" % str(base), value.cast(base), False)
d.putCallItem("exists", value, "exists")
@@ -522,7 +563,7 @@ def qdump__QHash(d, value):
d.putItemCount(size)
d.putNumChild(size)
if d.isExpanded():
isCompact = mapCompact(d.currentItemFormat(), keyType, valueType)
isCompact = d.isMapCompact(keyType, valueType)
node = hashDataFirstNode(value)
innerType = e_ptr.dereference().type
childType = innerType
@@ -716,18 +757,21 @@ def qdump__QLocale(d, value):
# QLocale data array from variable in qlocale.cpp.
# Default is 368 in Qt 4.8, 438 in Qt 5.0.1, the last one
# being 'System'.
global qqLocalesCount
if qqLocalesCount is None:
try:
qqLocalesCount = int(value(d.ns + 'locale_data_size'))
except:
qqLocalesCount = 438
try:
index = int(value["p"]["index"])
except:
index = int(value["d"]["d"]["m_index"])
check(index >= 0)
check(index <= qqLocalesCount)
#global qqLocalesCount
#if qqLocalesCount is None:
# #try:
# qqLocalesCount = int(value(d.ns + 'locale_data_size'))
# #except:
# qqLocalesCount = 438
#try:
# index = int(value["p"]["index"])
#except:
# try:
# index = int(value["d"]["d"]["m_index"])
# except:
# index = int(value["d"]["d"]["m_data"]...)
#check(index >= 0)
#check(index <= qqLocalesCount)
d.putStringValue(call(value, "name"))
d.putNumChild(0)
return
@@ -774,7 +818,7 @@ def qdumpHelper__Qt4_QMap(d, value, forceLong):
keyType = d.templateArgument(value.type, 0)
valueType = d.templateArgument(value.type, 1)
isCompact = mapCompact(d.currentItemFormat(), keyType, valueType)
isCompact = d.isMapCompact(keyType, valueType)
it = e_ptr["forward"].dereference()
@@ -782,7 +826,8 @@ def qdumpHelper__Qt4_QMap(d, value, forceLong):
# its size is most likely the offset of the 'forward' member therein.
# Or possibly 2 * sizeof(void *)
nodeType = d.lookupType(d.ns + "QMapNode<%s, %s>" % (keyType, valueType))
payloadSize = nodeType.sizeof - 2 * d.voidPtrSize
nodePointerType = nodeType.pointer()
payloadSize = nodeType.sizeof - 2 * nodePointerType.sizeof
if isCompact:
innerType = valueType
@@ -791,9 +836,8 @@ def qdumpHelper__Qt4_QMap(d, value, forceLong):
with Children(d, n, childType=innerType):
for i in xrange(n):
itd = it.dereference()
base = it.cast(d.charPtr()) - payloadSize
node = base.cast(nodeType.pointer()).dereference()
base = it.cast(d.charPtrType()) - payloadSize
node = base.cast(nodePointerType).dereference()
with SubItem(d, i):
d.putField("iname", d.currentIName)
if isCompact:
@@ -822,7 +866,7 @@ def qdumpHelper__Qt5_QMap(d, value, forceLong):
keyType = d.templateArgument(value.type, 0)
valueType = d.templateArgument(value.type, 1)
isCompact = mapCompact(d.currentItemFormat(), keyType, valueType)
isCompact = d.isMapCompact(keyType, valueType)
nodeType = d.lookupType(d.ns + "QMapNode<%s, %s>" % (keyType, valueType))
if isCompact:
innerType = valueType
@@ -864,7 +908,7 @@ def qdumpHelper__Qt5_QMap(d, value, forceLong):
def qdumpHelper__QMap(d, value, forceLong):
if value["d"].dereference().type.fields()[0].name == "backward":
if fieldAt(value["d"].dereference().type, 0).name == "backward":
qdumpHelper__Qt4_QMap(d, value, forceLong)
else:
qdumpHelper__Qt5_QMap(d, value, forceLong)
@@ -898,7 +942,7 @@ def qdump__QObject(d, value):
d.tryPutObjectNameValue(value)
try:
privateTypeName = self.ns + "QObjectPrivate"
privateTypeName = d.ns + "QObjectPrivate"
privateType = d.lookupType(privateTypeName)
staticMetaObject = value["staticMetaObject"]
except:
@@ -920,7 +964,10 @@ def qdump__QObject(d, value):
with Children(d):
d.putFields(value)
return
#warn("OBJECTNAME: %s " % objectName)
dd = value["d_ptr"]["d"]
d_ptr = dd.cast(privateType.pointer()).dereference()
#warn("D_PTR: %s " % d_ptr)
mo = d_ptr["metaObject"]
if not isAccessible(mo):
@@ -944,8 +991,8 @@ def qdump__QObject(d, value):
#warn("METADATA: %s " % metaData)
#warn("STRINGDATA: %s " % metaStringData)
#warn("TYPE: %s " % value.type)
#warn("INAME: %s " % d.currentIName())
#d.putEmptyValue()
#warn("INAME: %s " % d.currentIName)
d.putEmptyValue()
#QSignalMapper::staticMetaObject
#checkRef(d_ptr["ref"])
d.putNumChild(4)
@@ -1109,7 +1156,7 @@ def qdump__QObject(d, value):
if d.isExpanded():
pp = 0
with Children(d):
vectorType = connections.type.target().fields()[0].type
vectorType = fieldAt(connections.type.target(), 0).type
innerType = d.templateArgument(vectorType, 0)
# Should check: innerType == ns::QObjectPrivate::ConnectionList
p = gdb.Value(connections["p"]["array"]).cast(innerType.pointer())
@@ -1829,15 +1876,19 @@ def qdump__QVariant(d, value):
return innert
# User types.
type = str(call(value, "typeToName",
"('%sQVariant::Type')%d" % (d.ns, d_ptr["type"])))
if gdbLoaded:
type = str(call(value, "typeToName",
"('%sQVariant::Type')%d" % (d.ns, d_ptr["type"])))
if lldbLoaded:
type = str(call(value, "typeToName",
"(%sQVariant::Type)%d" % (d.ns, d_ptr["type"])))
type = type[type.find('"') + 1 : type.rfind('"')]
type = type.replace("Q", d.ns + "Q") # HACK!
type = type.replace("uint", "unsigned int") # HACK!
type = type.replace("COMMA", ",") # HACK!
warn("TYPE: %s" % type)
#warn("TYPE: %s" % type)
data = call(value, "constData")
warn("DATA: %s" % data)
#warn("DATA: %s" % data)
d.putEmptyValue(-99)
d.putType("%sQVariant (%s)" % (d.ns, type))
d.putNumChild(1)
@@ -1930,10 +1981,9 @@ def qdump__QxXmlAttributes(d, value):
def qdump____c_style_array__(d, value):
type = value.type.unqualified()
targetType = type.target()
typeName = str(type)
targetType = value[0].type
#d.putAddress(value.address)
d.putType(typeName)
d.putType(type)
d.putNumChild(1)
format = d.currentItemFormat()
isDefault = format == None and str(targetType.unqualified()) == "char"
@@ -1987,7 +2037,7 @@ def qdump__std__complex(d, value):
def qdump__std__deque(d, value):
innerType = templateArgument(value.type, 0)
innerType = d.templateArgument(value.type, 0)
innerSize = innerType.sizeof
bufsize = 1
if innerSize < 512:
@@ -2019,6 +2069,9 @@ def qdump__std__deque(d, value):
plast = pfirst + bufsize
pcur = pfirst
def qdump__std____debug__deque(d, value):
qdump__std__deque(d, value)
def qdump__std__list(d, value):
impl = value["_M_impl"]
@@ -2042,6 +2095,8 @@ def qdump__std__list(d, value):
d.putSubItem(i, (p + 1).cast(innerPointer).dereference())
p = p["_M_next"]
def qdump__std____debug__list(d, value):
qdump__std__list(d, value)
def qform__std__map():
return mapForms()
@@ -2065,7 +2120,7 @@ def qdump__std__map(d, value):
# So use this as workaround:
pairType = d.templateArgument(impl.type, 1)
pairPointer = pairType.pointer()
isCompact = mapCompact(d.currentItemFormat(), keyType, valueType)
isCompact = d.isMapCompact(keyType, valueType)
innerType = pairType
if isCompact:
innerType = valueType
@@ -2102,6 +2157,8 @@ def qdump__std__map(d, value):
while not isNull(node["_M_left"]):
node = node["_M_left"]
def qdump__std____debug__map(d, value):
qdump__std__map(d, value)
def stdTreeIteratorHelper(d, value):
pnode = value["_M_node"]
@@ -2178,6 +2235,8 @@ def qdump__std__set(d, value):
def qdump__std__stack(d, value):
qdump__std__deque(d, value["c"])
def qdump__std____debug__stack(d, value):
qdump__std__stack(d, value)
def qform__std__string():
return "Inline,In Separate Window"
@@ -2315,6 +2374,8 @@ def qdump__std__vector(d, value):
else:
d.putArrayData(type, start, size)
def qdump__std____debug__vector(d, value):
qdump__std__vector(d, value)
def qedit__std__string(expr, value):
cmd = "print (%s).assign(\"%s\")" % (expr, value)

View File

@@ -13,8 +13,12 @@ TEMPLATE = app
SOURCES += main.cpp \
qmlstreamwriter.cpp
OTHER_FILES += Info.plist
macx:QMAKE_INFO_PLIST = Info.plist
OTHER_FILES += Info.plist.in
macx {
info.input = Info.plist.in
info.output = $$DESTDIR/$${TARGET}.app/Contents/Info.plist
QMAKE_SUBSTITUTES += info
}
HEADERS += \
qmlstreamwriter.h

View File

@@ -60,10 +60,12 @@ symbian {
LIBS += -lavkon -lcone
}
}
OTHER_FILES+=Info.plist
OTHER_FILES+=Info.plist.in
mac {
QMAKE_INFO_PLIST=Info.plist
TARGET=QMLObserver
info.input = Info.plist.in
info.output = $$DESTDIR/$${TARGET}.app/Contents/Info.plist
QMAKE_SUBSTITUTES += info
ICON=qml.icns
} else {
TARGET=qmlobserver

View File

@@ -43,7 +43,7 @@ class ChangeAuxiliaryCommand
public:
ChangeAuxiliaryCommand();
ChangeAuxiliaryCommand(const QVector<PropertyValueContainer> &auxiliaryChangeVector);
explicit ChangeAuxiliaryCommand(const QVector<PropertyValueContainer> &auxiliaryChangeVector);
QVector<PropertyValueContainer> auxiliaryChanges() const;

View File

@@ -43,7 +43,7 @@ class ChangeBindingsCommand
public:
ChangeBindingsCommand();
ChangeBindingsCommand(const QVector<PropertyBindingContainer> &bindingChangeVector);
explicit ChangeBindingsCommand(const QVector<PropertyBindingContainer> &bindingChangeVector);
QVector<PropertyBindingContainer> bindingChanges() const;

View File

@@ -40,7 +40,7 @@ class ChangeFileUrlCommand
friend QDataStream &operator>>(QDataStream &in, ChangeFileUrlCommand &command);
public:
ChangeFileUrlCommand();
ChangeFileUrlCommand(const QUrl &fileUrl);
explicit ChangeFileUrlCommand(const QUrl &fileUrl);
QUrl fileUrl() const;

View File

@@ -43,7 +43,7 @@ class ChangeIdsCommand
friend QDataStream &operator>>(QDataStream &in, ChangeIdsCommand &command);
public:
ChangeIdsCommand();
ChangeIdsCommand(const QVector<IdContainer> &idVector);
explicit ChangeIdsCommand(const QVector<IdContainer> &idVector);
QVector<IdContainer> ids() const;

View File

@@ -41,7 +41,7 @@ class ChangeNodeSourceCommand
friend QDataStream &operator>>(QDataStream &in, ChangeNodeSourceCommand &command);
public:
ChangeNodeSourceCommand();
ChangeNodeSourceCommand(qint32 instanceId, const QString &nodeSource);
explicit ChangeNodeSourceCommand(qint32 instanceId, const QString &nodeSource);
qint32 instanceId() const;
QString nodeSource() const;

View File

@@ -43,7 +43,7 @@ class ChangeStateCommand
public:
ChangeStateCommand();
ChangeStateCommand(qint32 stateInstanceId);
explicit ChangeStateCommand(qint32 stateInstanceId);
qint32 stateInstanceId() const;

View File

@@ -43,7 +43,7 @@ class ChangeValuesCommand
public:
ChangeValuesCommand();
ChangeValuesCommand(const QVector<PropertyValueContainer> &valueChangeVector);
explicit ChangeValuesCommand(const QVector<PropertyValueContainer> &valueChangeVector);
QVector<PropertyValueContainer> valueChanges() const;

View File

@@ -41,7 +41,7 @@ class ChildrenChangedCommand
friend QDataStream &operator>>(QDataStream &in, ChildrenChangedCommand &command);
public:
ChildrenChangedCommand();
ChildrenChangedCommand(qint32 parentInstanceId, const QVector<qint32> &childrenInstancesconst, const QVector<InformationContainer> &informationVector);
explicit ChildrenChangedCommand(qint32 parentInstanceId, const QVector<qint32> &childrenInstancesconst, const QVector<InformationContainer> &informationVector);
QVector<qint32> childrenInstances() const;
qint32 parentInstanceId() const;

View File

@@ -42,7 +42,7 @@ class CompleteComponentCommand
public:
CompleteComponentCommand();
CompleteComponentCommand(const QVector<qint32> &container);
explicit CompleteComponentCommand(const QVector<qint32> &container);
QVector<qint32> instances() const;

View File

@@ -41,7 +41,7 @@ class ComponentCompletedCommand
public:
ComponentCompletedCommand();
ComponentCompletedCommand(const QVector<qint32> &container);
explicit ComponentCompletedCommand(const QVector<qint32> &container);
QVector<qint32> instances() const;

View File

@@ -43,7 +43,7 @@ class CreateInstancesCommand
public:
CreateInstancesCommand();
CreateInstancesCommand(const QVector<InstanceContainer> &container);
explicit CreateInstancesCommand(const QVector<InstanceContainer> &container);
QVector<InstanceContainer> instances() const;

View File

@@ -49,7 +49,7 @@ class CreateSceneCommand
public:
CreateSceneCommand();
CreateSceneCommand(const QVector<InstanceContainer> &instanceContainer,
explicit CreateSceneCommand(const QVector<InstanceContainer> &instanceContainer,
const QVector<ReparentContainer> &reparentContainer,
const QVector<IdContainer> &idVector,
const QVector<PropertyValueContainer> &valueChangeVector,

View File

@@ -49,7 +49,7 @@ public:
};
DebugOutputCommand();
DebugOutputCommand(const QString &text, Type type);
explicit DebugOutputCommand(const QString &text, Type type);
qint32 type() const;
QString text() const;

View File

@@ -44,7 +44,7 @@ class InformationChangedCommand
public:
InformationChangedCommand();
InformationChangedCommand(const QVector<InformationContainer> &informationVector);
explicit InformationChangedCommand(const QVector<InformationContainer> &informationVector);
QVector<InformationContainer> informations() const;

View File

@@ -40,7 +40,7 @@ class PixmapChangedCommand
friend QDataStream &operator>>(QDataStream &in, PixmapChangedCommand &command);
public:
PixmapChangedCommand();
PixmapChangedCommand(const QVector<ImageContainer> &imageVector);
explicit PixmapChangedCommand(const QVector<ImageContainer> &imageVector);
QVector<ImageContainer> images() const;

View File

@@ -44,7 +44,7 @@ class RemoveInstancesCommand
public:
RemoveInstancesCommand();
RemoveInstancesCommand(const QVector<qint32> &idVector);
explicit RemoveInstancesCommand(const QVector<qint32> &idVector);
QVector<qint32> instanceIds() const;

View File

@@ -42,7 +42,7 @@ class RemovePropertiesCommand
friend QDataStream &operator>>(QDataStream &in, RemovePropertiesCommand &command);
public:
RemovePropertiesCommand();
RemovePropertiesCommand(const QVector<PropertyAbstractContainer> &properties);
explicit RemovePropertiesCommand(const QVector<PropertyAbstractContainer> &properties);
QVector<PropertyAbstractContainer> properties() const;

View File

@@ -43,7 +43,7 @@ class RemoveSharedMemoryCommand
public:
RemoveSharedMemoryCommand();
RemoveSharedMemoryCommand(const QString &typeName, const QVector<qint32> &keyNumberVector);
explicit RemoveSharedMemoryCommand(const QString &typeName, const QVector<qint32> &keyNumberVector);
QString typeName() const;
QVector<qint32> keyNumbers() const;

View File

@@ -43,7 +43,7 @@ class ReparentInstancesCommand
public:
ReparentInstancesCommand();
ReparentInstancesCommand(const QVector<ReparentContainer> &container);
explicit ReparentInstancesCommand(const QVector<ReparentContainer> &container);
QVector<ReparentContainer> reparentInstances() const;

View File

@@ -41,7 +41,7 @@ class StatePreviewImageChangedCommand
friend QDataStream &operator>>(QDataStream &in, StatePreviewImageChangedCommand &command);
public:
StatePreviewImageChangedCommand();
StatePreviewImageChangedCommand(const QVector<ImageContainer> &imageVector);
explicit StatePreviewImageChangedCommand(const QVector<ImageContainer> &imageVector);
QVector<ImageContainer> previews() const;

View File

@@ -43,7 +43,7 @@ class SynchronizeCommand
public:
SynchronizeCommand();
SynchronizeCommand(int synchronizeId);
explicit SynchronizeCommand(int synchronizeId);
int synchronizeId() const;

View File

@@ -44,7 +44,7 @@ class TokenCommand
public:
TokenCommand();
TokenCommand(const QString &tokenName, qint32 tokenNumber, const QVector<qint32> &instances);
explicit TokenCommand(const QString &tokenName, qint32 tokenNumber, const QVector<qint32> &instances);
QString tokenName() const;
qint32 tokenNumber() const;

View File

@@ -44,7 +44,7 @@ class ValuesChangedCommand
public:
ValuesChangedCommand();
ValuesChangedCommand(const QVector<PropertyValueContainer> &valueChangeVector);
explicit ValuesChangedCommand(const QVector<PropertyValueContainer> &valueChangeVector);
QVector<PropertyValueContainer> valueChanges() const;
quint32 keyNumber() const;

View File

@@ -126,7 +126,6 @@ QList<ServerNodeInstance> NodeInstanceServer::createInstances(const QVector<Ins
void NodeInstanceServer::createInstances(const CreateInstancesCommand &command)
{
createInstances(command.instances());
refreshBindings();
startRenderTimer();
}
@@ -321,8 +320,6 @@ void NodeInstanceServer::completeComponent(const CompleteComponentCommand &comma
}
}
refreshBindings();
startRenderTimer();
}

View File

@@ -96,7 +96,6 @@ void NodeInstanceSignalSpy::registerValueType(const QMetaProperty &metaProperty,
index < valueType->metaObject()->propertyCount();
index++) {
QMetaProperty valueTypeMetaProperty = valueType->metaObject()->property(index);
qDebug() << "spy value property: " << propertyPrefix + PropertyName(metaProperty.name()) + "." + valueTypeMetaProperty.name();
m_indexPropertyHash.insert(methodeOffset, propertyPrefix + PropertyName(metaProperty.name()) + "." + valueTypeMetaProperty.name());
}
@@ -110,7 +109,6 @@ void NodeInstanceSignalSpy::registerChildObject(const QMetaProperty &metaPropert
&& QQmlMetaType::isQObject(metaProperty.userType())
&& QLatin1String(metaProperty.name()) != "parent") {
QObject *childObject = QQmlMetaType::toQObject(metaProperty.read(spiedObject));
qDebug() << "spy child property: " << childObject << metaProperty.name();
if (childObject) {
for (int index = QObject::staticMetaObject.propertyOffset();

View File

@@ -153,32 +153,9 @@ void ObjectNodeInstance::setNodeInstanceServer(NodeInstanceServer *server)
m_nodeInstanceServer = server;
}
static bool hasPropertiesWitoutNotifications(const QMetaObject *metaObject)
{
for (int propertyIndex = QObject::staticMetaObject.propertyCount(); propertyIndex < metaObject->propertyCount(); propertyIndex++) {
if (!metaObject->property(propertyIndex).hasNotifySignal())
return true;
}
return false;
}
void ObjectNodeInstance::initializePropertyWatcher(const ObjectNodeInstance::Pointer &objectNodeInstance)
{
const QMetaObject *metaObject = objectNodeInstance->object()->metaObject();
m_metaObject = NodeInstanceMetaObject::createNodeInstanceMetaObject(objectNodeInstance, nodeInstanceServer()->engine());
for (int propertyIndex = QObject::staticMetaObject.propertyCount(); propertyIndex < metaObject->propertyCount(); propertyIndex++) {
if (QQmlMetaType::isQObject(metaObject->property(propertyIndex).userType())) {
QObject *propertyObject = QQmlMetaType::toQObject(metaObject->property(propertyIndex).read(objectNodeInstance->object()));
if (propertyObject && hasPropertiesWitoutNotifications(propertyObject->metaObject())) {
NodeInstanceMetaObject::createNodeInstanceMetaObject(objectNodeInstance,
propertyObject,
metaObject->property(propertyIndex).name(),
nodeInstanceServer()->engine());
}
}
}
m_signalSpy.setObjectNodeInstance(objectNodeInstance);
}

View File

@@ -36,6 +36,7 @@
#include <designersupport.h>
#include <addimportcontainer.h>
#include <createscenecommand.h>
#include <reparentinstancescommand.h>
namespace QmlDesigner {
@@ -149,4 +150,11 @@ void Qt5NodeInstanceServer::clearScene(const ClearSceneCommand &command)
NodeInstanceServer::clearScene(command);
}
void Qt5NodeInstanceServer::reparentInstances(const ReparentInstancesCommand &command)
{
NodeInstanceServer::reparentInstances(command.reparentInstances());
startRenderTimer();
}
} // QmlDesigner

View File

@@ -57,6 +57,7 @@ public:
void createScene(const CreateSceneCommand &command) Q_DECL_OVERRIDE;
void clearScene(const ClearSceneCommand &command) Q_DECL_OVERRIDE;
void reparentInstances(const ReparentInstancesCommand &command) Q_DECL_OVERRIDE;
protected:
void initializeView(const QVector<AddImportContainer> &importVector) Q_DECL_OVERRIDE;

View File

@@ -29,7 +29,7 @@ DEFINES -= QT_NO_CAST_FROM_ASCII
OTHER_FILES += Info.plist.in
macx {
info.input = Info.plist.in
info.input = $$PWD/Info.plist.in
info.output = $$DESTDIR/$${TARGET}.app/Contents/Info.plist
QMAKE_SUBSTITUTES += info
} else {

View File

@@ -45,4 +45,10 @@
<style name="JsScopeVar" foreground="#8888ff" italic="true"/>
<style name="JsImportVar" foreground="#8888ff" italic="true"/>
<style name="JsGlobalVar" foreground="#8888ff" italic="true"/>
<style name="DillFileLine" foreground="#000000" background="#d7d700"/>
<style name="DiffContextLine" foreground="#000000" background="#8aaab6"/>
<style name="DiffSourceLine" background="#8c2d2d"/>
<style name="DiffSourceChar" foreground="#000000" background="#c34141"/>
<style name="DiffDestLine" background="#2d8c2d"/>
<style name="DiffDestChar" foreground="#000000" background="#41c341"/>
</style-scheme>

View File

@@ -5,6 +5,12 @@
<style name="CurrentLine" foreground="#000000" background="#f2f2f2"/>
<style name="DiffFile"/>
<style name="DiffLocation"/>
<style name="DillFileLine" foreground="#ffffff" background="#000000"/>
<style name="DiffContextLine" foreground="#ffffff" background="#7f7f7f"/>
<style name="DiffSourceLine" background="#d7d7d7"/>
<style name="DiffSourceChar" background="#afafaf"/>
<style name="DiffDestLine" background="#d7d7d7"/>
<style name="DiffDestChar" background="#afafaf"/>
<style name="Doxygen.Comment" foreground="#808080"/>
<style name="Doxygen.Tag" foreground="#808080" italic="true"/>
<style name="Field"/>

View File

@@ -53,5 +53,11 @@
<style name="JsScopeVar" foreground="#8888ff" italic="true"/>
<style name="JsImportVar" foreground="#8888ff" italic="true"/>
<style name="JsGlobalVar" foreground="#8888ff" italic="true"/>
<style name="DillFileLine" foreground="#404040" background="#dcb178"/>
<style name="DiffContextLine" foreground="#404040" background="#97bac7"/>
<style name="DiffSourceLine" background="#8c2d2d"/>
<style name="DiffSourceChar" background="#c34141"/>
<style name="DiffDestLine" background="#277027"/>
<style name="DiffDestChar" background="#339d33"/>
</style-scheme>

View File

@@ -13,6 +13,4 @@ public:
~%ObjectName%();
};
QML_DECLARE_TYPE(%ObjectName%)
#endif // %ObjectName:u%_H

File diff suppressed because it is too large Load Diff

View File

@@ -1,8 +1,8 @@
import qbs.base 1.0
Product {
name: "Translations"
type: "qm"
name: "translations"
Depends { name: "Qt.core" }
files: "*.ts"

View File

@@ -64,8 +64,8 @@ Rectangle {
y: 60
anchors.right: parent.right
anchors.rightMargin: 240
anchors.right: comboBox.left
anchors.rightMargin: 20
anchors.left: parent.left
anchors.leftMargin: 60
@@ -78,10 +78,9 @@ Rectangle {
anchors.verticalCenter: searchBar.verticalCenter
anchors.left: searchBar.right
width: 200
anchors.rightMargin: 80
anchors.right: parent.right
anchors.leftMargin: 20
model: qtVersionModel
onCurrentIndexChanged: {

View File

@@ -4,6 +4,7 @@ Product {
name: "SharedContent"
Group {
name: "Unconditional"
qbs.install: true
qbs.installDir: project.ide_data_path
prefix: "qtcreator/"
@@ -25,6 +26,7 @@ Product {
}
Group {
name: "Conditional"
qbs.install: true
qbs.installDir: project.ide_data_path + "/externaltools"
prefix: "../src/share/qtcreator/externaltools/"

View File

@@ -497,14 +497,17 @@ int main(int argc, char **argv)
errorOverview.exec();
}
// Set up lock and remote arguments.
app.initialize();
// Set up remote arguments.
QObject::connect(&app, SIGNAL(messageReceived(QString,QObject*)),
&pluginManager, SLOT(remoteArguments(QString,QObject*)));
QObject::connect(&app, SIGNAL(fileOpenRequest(QString)), coreplugin->plugin(),
SLOT(fileOpenRequest(QString)));
// quit when last window (relevant window, see WA_QuitOnClose) is closed
// this should actually be the default, but doesn't work in Qt 5
// QTBUG-31569
QObject::connect(&app, SIGNAL(lastWindowClosed()), &app, SLOT(quit()));
// shutdown plugin manager on the exit
QObject::connect(&app, SIGNAL(aboutToQuit()), &pluginManager, SLOT(shutdown()));

View File

@@ -4419,8 +4419,9 @@ unsigned AliasDeclarationAST::firstToken() const
{
if (using_token)
return using_token;
if (identifier_token)
return identifier_token;
if (name)
if (unsigned candidate = name->firstToken())
return candidate;
if (equal_token)
return equal_token;
if (typeId)
@@ -4441,8 +4442,9 @@ unsigned AliasDeclarationAST::lastToken() const
return candidate;
if (equal_token)
return equal_token + 1;
if (identifier_token)
return identifier_token + 1;
if (name)
if (unsigned candidate = name->lastToken())
return candidate;
if (using_token)
return using_token + 1;
return 1;

View File

@@ -2432,18 +2432,22 @@ class CPLUSPLUS_EXPORT AliasDeclarationAST: public DeclarationAST
{
public:
unsigned using_token;
unsigned identifier_token;
NameAST *name;
unsigned equal_token;
TypeIdAST *typeId;
unsigned semicolon_token;
public: // annotations
Declaration *symbol;
public:
AliasDeclarationAST()
: using_token(0)
, identifier_token(0)
, name(0)
, equal_token(0)
, typeId(0)
, semicolon_token(0)
, symbol(0)
{}
virtual AliasDeclarationAST *asAliasDeclaration() { return this; }

View File

@@ -890,7 +890,8 @@ AliasDeclarationAST *AliasDeclarationAST::clone(MemoryPool *pool) const
{
AliasDeclarationAST *ast = new (pool) AliasDeclarationAST;
ast->using_token = using_token;
ast->identifier_token = identifier_token;
if (name)
ast->name = name->clone(pool);
ast->equal_token = equal_token;
if (typeId)
ast->typeId = typeId->clone(pool);

View File

@@ -1511,7 +1511,10 @@ bool ASTMatcher::match(AliasDeclarationAST *node, AliasDeclarationAST *pattern)
pattern->using_token = node->using_token;
pattern->identifier_token = node->identifier_token;
if (! pattern->name)
pattern->name = node->name;
else if (! AST::match(node->name, pattern->name, this))
return false;
pattern->equal_token = node->equal_token;

View File

@@ -584,9 +584,10 @@ public:
return __ast;
}
AliasDeclarationAST *AliasDeclaration(TypeIdAST *typeId = 0)
AliasDeclarationAST *AliasDeclaration(NameAST *name = 0, TypeIdAST *typeId = 0)
{
AliasDeclarationAST *__ast = new (&pool) AliasDeclarationAST;
__ast->name = name;
__ast->typeId = typeId;
return __ast;
}

View File

@@ -646,6 +646,7 @@ void NamespaceAliasDefinitionAST::accept0(ASTVisitor *visitor)
void AliasDeclarationAST::accept0(ASTVisitor *visitor)
{
if (visitor->visit(this)) {
accept(name, visitor);
accept(typeId, visitor);
}
visitor->endVisit(this);

View File

@@ -2066,6 +2066,27 @@ bool Bind::visit(QtInterfacesDeclarationAST *ast)
return false;
}
bool Bind::visit(AliasDeclarationAST *ast)
{
if (!ast->name)
return false;
const Name *name = this->name(ast->name);
FullySpecifiedType ty = expression(ast->typeId);
ty.setTypedef(true);
Declaration *decl = control()->newDeclaration(ast->name->firstToken(), name);
decl->setType(ty);
decl->setStorage(Symbol::Typedef);
ast->symbol = decl;
if (_scope->isClass())
decl->setVisibility(_visibility);
_scope->addMember(decl);
return false;
}
bool Bind::visit(AsmDefinitionAST *ast)
{
(void) ast;

View File

@@ -209,6 +209,7 @@ protected:
virtual bool visit(QtEnumDeclarationAST *ast);
virtual bool visit(QtFlagsDeclarationAST *ast);
virtual bool visit(QtInterfacesDeclarationAST *ast);
virtual bool visit(AliasDeclarationAST *ast);
virtual bool visit(AsmDefinitionAST *ast);
virtual bool visit(ExceptionDeclarationAST *ast);
virtual bool visit(FunctionDefinitionAST *ast);

View File

@@ -868,7 +868,9 @@ bool Parser::parseAliasDeclaration(DeclarationAST *&node)
AliasDeclarationAST *alias = new (_pool) AliasDeclarationAST;
alias->using_token = consumeToken();
alias->identifier_token = consumeToken();
SimpleNameAST *name = new (_pool) SimpleNameAST;
name->identifier_token = consumeToken();
alias->name = name;
// ### attributes!
while (LA() != T_EQUAL)

View File

@@ -341,15 +341,15 @@ QStringList Document::includedFiles() const
{
QStringList files;
foreach (const Include &i, _includes)
files.append(i.fileName());
files.append(i.resolvedFileName());
files.removeDuplicates();
return files;
}
// This assumes to be called with a QDir::cleanPath cleaned fileName.
void Document::addIncludeFile(const QString &fileName, unsigned line)
void Document::addIncludeFile(const Document::Include &include)
{
_includes.append(Include(fileName, line));
_includes.append(include);
}
void Document::appendMacro(const Macro &macro)

View File

@@ -33,6 +33,7 @@
#include "Macro.h"
#include <cplusplus/CPlusPlusForwardDeclarations.h>
#include <cplusplus/PreprocessorClient.h>
#include <QSharedPointer>
#include <QDateTime>
@@ -75,9 +76,6 @@ public:
QString fileName() const;
QStringList includedFiles() const;
void addIncludeFile(const QString &fileName, unsigned line);
void appendMacro(const Macro &macro);
void addMacroUse(const Macro &macro, unsigned offset, unsigned length,
unsigned beginLine,
@@ -233,22 +231,31 @@ public:
};
class Include {
QString _fileName;
QString _resolvedFileName;
QString _unresolvedFileName;
unsigned _line;
Client::IncludeType _type;
public:
Include(const QString &fileName, unsigned line)
: _fileName(fileName), _line(line)
Include(const QString &unresolvedFileName, const QString &resolvedFileName, unsigned line,
Client::IncludeType type)
: _resolvedFileName(resolvedFileName)
, _unresolvedFileName(unresolvedFileName)
, _line(line)
, _type(type)
{ }
QString fileName() const
{ return _fileName; }
QString resolvedFileName() const
{ return _resolvedFileName; }
QString unresolvedFileName() const
{ return _unresolvedFileName; }
unsigned line() const
{ return _line; }
bool resolved() const
{ return QFileInfo(_fileName).isAbsolute(); }
Client::IncludeType type() const
{ return _type; }
};
class MacroUse: public Block {
@@ -302,6 +309,9 @@ public:
}
};
QStringList includedFiles() const;
void addIncludeFile(const Include &include);
QList<Include> includes() const
{ return _includes; }

View File

@@ -53,7 +53,7 @@ QByteArray FastPreprocessor::run(Document::Ptr newDoc, const QString &source)
mergeEnvironment(Preprocessor::configurationFileName);
foreach (const Document::Include &i, doc->includes())
mergeEnvironment(i.fileName());
mergeEnvironment(i.resolvedFileName());
}
const QByteArray preprocessed = _preproc.run(fileName, source);
@@ -62,13 +62,13 @@ QByteArray FastPreprocessor::run(Document::Ptr newDoc, const QString &source)
return preprocessed;
}
void FastPreprocessor::sourceNeeded(unsigned line, const QString &fileName, IncludeType)
void FastPreprocessor::sourceNeeded(unsigned line, const QString &fileName,
IncludeType mode)
{
Q_ASSERT(_currentDoc);
// CHECKME: Is that cleanName needed?
QString cleanName = QDir::cleanPath(fileName);
_currentDoc->addIncludeFile(cleanName, line);
_currentDoc->addIncludeFile(Document::Include(fileName, cleanName, line, mode));
mergeEnvironment(fileName);
}
@@ -79,7 +79,7 @@ void FastPreprocessor::mergeEnvironment(const QString &fileName)
if (Document::Ptr doc = _snapshot.document(fileName)) {
foreach (const Document::Include &i, doc->includes())
mergeEnvironment(i.fileName());
mergeEnvironment(i.resolvedFileName());
_env.addMacros(doc->definedMacros());
}

View File

@@ -57,7 +57,7 @@ public:
QByteArray run(Document::Ptr newDoc, const QString &source);
// CPlusPlus::Client
virtual void sourceNeeded(unsigned line, const QString &fileName, IncludeType);
virtual void sourceNeeded(unsigned line, const QString &fileName, IncludeType mode);
virtual void macroAdded(const Macro &);

View File

@@ -305,7 +305,8 @@ ClassOrNamespace *LookupContext::globalNamespace() const
}
ClassOrNamespace *LookupContext::lookupType(const Name *name, Scope *scope,
ClassOrNamespace* enclosingTemplateInstantiation) const
ClassOrNamespace* enclosingTemplateInstantiation,
QSet<const Declaration *> typedefsBeingResolved) const
{
if (! scope) {
return 0;
@@ -324,8 +325,14 @@ ClassOrNamespace *LookupContext::lookupType(const Name *name, Scope *scope,
Overview oo;
qDebug() << "Looks like" << oo(name) << "is a typedef for" << oo(d->type());
#endif // DEBUG_LOOKUP
if (const NamedType *namedTy = d->type()->asNamedType())
return lookupType(namedTy->name(), scope);
if (const NamedType *namedTy = d->type()->asNamedType()) {
// Stop on recursive typedef declarations
if (typedefsBeingResolved.contains(d))
return 0;
return lookupType(namedTy->name(), scope, 0,
QSet<const Declaration *>(typedefsBeingResolved)
<< d);
}
}
}
} else if (UsingDeclaration *ud = m->asUsingDeclaration()) {
@@ -1364,7 +1371,7 @@ void CreateBindings::process(Document::Ptr doc)
_processed.insert(globalNamespace);
foreach (const Document::Include &i, doc->includes()) {
if (Document::Ptr incl = _snapshot.document(i.fileName()))
if (Document::Ptr incl = _snapshot.document(i.resolvedFileName()))
process(incl);
}

View File

@@ -289,7 +289,9 @@ public:
QList<LookupItem> lookup(const Name *name, Scope *scope) const;
ClassOrNamespace *lookupType(const Name *name, Scope *scope,
ClassOrNamespace* enclosingTemplateInstantiation = 0) const;
ClassOrNamespace* enclosingTemplateInstantiation = 0,
QSet<const Declaration *> typedefsBeingResolved
= QSet<const Declaration *>()) const;
ClassOrNamespace *lookupType(Symbol *symbol,
ClassOrNamespace* enclosingTemplateInstantiation = 0) const;
ClassOrNamespace *lookupParent(Symbol *symbol) const;

View File

@@ -77,11 +77,13 @@ static QList<_Tp> removeDuplicates(const QList<_Tp> &results)
/////////////////////////////////////////////////////////////////////
// ResolveExpression
/////////////////////////////////////////////////////////////////////
ResolveExpression::ResolveExpression(const LookupContext &context)
ResolveExpression::ResolveExpression(const LookupContext &context,
const QSet<const Declaration *> &autoDeclarationsBeingResolved)
: ASTVisitor(context.expressionDocument()->translationUnit()),
_scope(0),
_context(context),
bind(context.expressionDocument()->translationUnit()),
_autoDeclarationsBeingResolved(autoDeclarationsBeingResolved),
_reference(false)
{ }
@@ -521,6 +523,10 @@ bool ResolveExpression::visit(SimpleNameAST *ast)
if (!decl)
continue;
// Stop on recursive auto declarations
if (_autoDeclarationsBeingResolved.contains(decl))
continue;
const StringLiteral *initializationString = decl->getInitializer();
if (initializationString == 0)
continue;
@@ -535,7 +541,8 @@ bool ResolveExpression::visit(SimpleNameAST *ast)
TypeOfExpression exprTyper;
Document::Ptr doc = _context.snapshot().document(QString::fromLocal8Bit(decl->fileName()));
exprTyper.init(doc, _context.snapshot(), _context.bindings());
exprTyper.init(doc, _context.snapshot(), _context.bindings(),
QSet<const Declaration* >(_autoDeclarationsBeingResolved) << decl);
Document::Ptr exprDoc =
documentForExpression(exprTyper.preprocessedExpression(initializer));
@@ -545,8 +552,8 @@ bool ResolveExpression::visit(SimpleNameAST *ast)
if (deduceAuto._block)
continue;
const QList<LookupItem> &typeItems =
exprTyper(extractExpressionAST(exprDoc), exprDoc, decl->enclosingScope());
const QList<LookupItem> &typeItems = exprTyper(extractExpressionAST(exprDoc), exprDoc,
decl->enclosingScope());
if (typeItems.empty())
continue;

View File

@@ -43,7 +43,9 @@ namespace CPlusPlus {
class CPLUSPLUS_EXPORT ResolveExpression: protected ASTVisitor
{
public:
ResolveExpression(const LookupContext &context);
ResolveExpression(const LookupContext &context,
const QSet<const Declaration *> &autoDeclarationsBeingResolved
= QSet<const Declaration *>());
virtual ~ResolveExpression();
QList<LookupItem> operator()(ExpressionAST *ast, Scope *scope);
@@ -126,6 +128,7 @@ private:
const LookupContext& _context;
Bind bind;
QList<LookupItem> _results;
QSet<const Declaration *> _autoDeclarationsBeingResolved;
bool _reference;
};

View File

@@ -50,7 +50,7 @@ void SnapshotSymbolVisitor::accept(Document::Ptr doc, QSet<QString> *processed)
processed->insert(doc->fileName());
foreach (const Document::Include &i, doc->includes()) {
if (Document::Ptr incl = _snapshot.document(i.fileName()))
if (Document::Ptr incl = _snapshot.document(i.resolvedFileName()))
accept(incl, processed);
}

View File

@@ -60,7 +60,8 @@ void TypeOfExpression::reset()
}
void TypeOfExpression::init(Document::Ptr thisDocument, const Snapshot &snapshot,
QSharedPointer<CreateBindings> bindings)
QSharedPointer<CreateBindings> bindings,
const QSet<const Declaration *> &autoDeclarationsBeingResolved)
{
m_thisDocument = thisDocument;
m_snapshot = snapshot;
@@ -69,6 +70,7 @@ void TypeOfExpression::init(Document::Ptr thisDocument, const Snapshot &snapshot
m_lookupContext = LookupContext();
m_bindings = bindings;
m_environment.clear();
m_autoDeclarationsBeingResolved = autoDeclarationsBeingResolved;
}
QList<LookupItem> TypeOfExpression::operator()(const QByteArray &utf8code,
@@ -113,7 +115,7 @@ QList<LookupItem> TypeOfExpression::operator()(ExpressionAST *expression,
m_lookupContext.setBindings(m_bindings);
m_lookupContext.setExpandTemplates(m_expandTemplates);
ResolveExpression resolve(m_lookupContext);
ResolveExpression resolve(m_lookupContext, m_autoDeclarationsBeingResolved);
const QList<LookupItem> items = resolve(m_ast, scope);
if (! m_bindings)
@@ -135,7 +137,7 @@ QList<LookupItem> TypeOfExpression::reference(ExpressionAST *expression,
m_lookupContext.setBindings(m_bindings);
m_lookupContext.setExpandTemplates(m_expandTemplates);
ResolveExpression resolve(m_lookupContext);
ResolveExpression resolve(m_lookupContext, m_autoDeclarationsBeingResolved);
const QList<LookupItem> items = resolve.reference(m_ast, scope);
if (! m_bindings)
@@ -176,7 +178,7 @@ void TypeOfExpression::processEnvironment(Document::Ptr doc, Environment *env,
processed->insert(doc->fileName());
foreach (const Document::Include &incl, doc->includes())
processEnvironment(m_snapshot.document(incl.fileName()), env, processed);
processEnvironment(m_snapshot.document(incl.resolvedFileName()), env, processed);
foreach (const Macro &macro, doc->definedMacros())
env->bind(macro);

View File

@@ -59,8 +59,11 @@ public:
* Also clears the lookup context, so can be used to make sure references
* to the documents previously used are removed.
*/
void init(Document::Ptr thisDocument, const Snapshot &snapshot,
QSharedPointer<CreateBindings> bindings = QSharedPointer<CreateBindings>());
void init(Document::Ptr thisDocument,
const Snapshot &snapshot,
QSharedPointer<CreateBindings> bindings = QSharedPointer<CreateBindings>(),
const QSet<const Declaration *> &autoDeclarationsBeingResolved
= QSet<const Declaration *>());
void reset();
@@ -152,6 +155,8 @@ private:
// Keep the expression documents and thus all the symbols and
// their types alive until they are not needed any more.
QList<Document::Ptr> m_documents;
QSet<const Declaration *> m_autoDeclarationsBeingResolved;
};
ExpressionAST CPLUSPLUS_EXPORT *extractExpressionAST(Document::Ptr doc);

View File

@@ -14,6 +14,7 @@ QtcLibrary {
Depends { name: "Qt.widgets" }
Group {
name: "ThirdPartyCPlusPlus"
prefix: "../3rdparty/cplusplus/"
files: [
"AST.cpp",

View File

@@ -1048,7 +1048,7 @@ bool Preprocessor::handleIdentifier(PPToken *tk)
argRefs);
}
if (!handleFunctionLikeMacro(tk, macro, body, allArgTks, baseLine)) {
if (!handleFunctionLikeMacro(macro, body, allArgTks, baseLine)) {
if (m_client && !idTk.expanded())
m_client->stopExpandingMacro(idTk.offset, *macro);
return false;
@@ -1119,8 +1119,7 @@ bool Preprocessor::handleIdentifier(PPToken *tk)
return true;
}
bool Preprocessor::handleFunctionLikeMacro(PPToken *tk,
const Macro *macro,
bool Preprocessor::handleFunctionLikeMacro(const Macro *macro,
QVector<PPToken> &body,
const QVector<QVector<PPToken> > &actuals,
unsigned baseLine)
@@ -1220,9 +1219,6 @@ bool Preprocessor::handleFunctionLikeMacro(PPToken *tk,
body = expanded;
body.squeeze();
// Next token to be lexed after the expansion.
pushToken(tk);
return true;
}
@@ -1479,9 +1475,9 @@ bool Preprocessor::collectActualArguments(PPToken *tk, QVector<QVector<PPToken>
actuals->append(tokens);
}
if (tk->is(T_RPAREN))
lex(tk);
//###TODO: else error message
if (!tk->is(T_RPAREN)) {
//###TODO: else error message
}
return true;
}

View File

@@ -205,8 +205,7 @@ private:
void lex(PPToken *tk);
void skipPreprocesorDirective(PPToken *tk);
bool handleIdentifier(PPToken *tk);
bool handleFunctionLikeMacro(PPToken *tk,
const Macro *macro,
bool handleFunctionLikeMacro(const Macro *macro,
QVector<PPToken> &body,
const QVector<QVector<PPToken> > &actuals,
unsigned lineRef);

View File

@@ -493,8 +493,9 @@ QrcParser::Ptr QrcCachePrivate::updatePath(const QString &path)
{
QMutexLocker l(&m_mutex);
QPair<QrcParser::Ptr,int> currentValue = m_cache.value(path, qMakePair(QrcParser::Ptr(0), 0));
QTC_CHECK(currentValue.second > 0);
currentValue.first = newParser;
if (currentValue.second == 0)
currentValue.second = 1; // add qrc files that are not in the resources of a project
m_cache.insert(path, currentValue);
return currentValue.first;
}

View File

@@ -391,7 +391,7 @@ QList<EnvironmentItem> Environment::diff(const Environment &other) const
return result;
}
bool Environment::hasKey(const QString &key)
bool Environment::hasKey(const QString &key) const
{
return m_values.contains(key);
}

View File

@@ -77,7 +77,7 @@ public:
void modify(const QList<EnvironmentItem> &list);
/// Return the Environment changes necessary to modify this into the other environment.
QList<EnvironmentItem> diff(const Environment &other) const;
bool hasKey(const QString &key);
bool hasKey(const QString &key) const;
QString userName() const;

Some files were not shown because too many files have changed in this diff Show More